Конфигурация против кода: где провести границу
Адрес базы данных — конфигурация, а правило расчёта скидки — код. Но между ними хватает спорных случаев: от лимитов и таймаутов до флагов функций. Разбираем, как провести границу, чтобы не собирать приложение из случайных переключателей.

Если для изменения лимита загрузки нужно пересобирать сервис, настройка, вероятно, зашита в код зря. Если же бизнес-правило можно незаметно поменять одной переменной окружения, вы рискуете получить поведение, которое невозможно объяснить по истории коммитов. Граница между конфигурацией и кодом определяет, кто может менять систему, как проверять изменение и насколько быстро можно восстановить прежнее поведение.
Сначала разделите способы изменения
Полезно различать не «значения в файле» и «строки в исходниках», а два разных вида изменений. Код описывает поведение приложения: правила, последовательность действий, обработку ошибок. Конфигурация выбирает параметры этого поведения для конкретного окружения или запуска.
Например, код отправляет письма через настроенный почтовый сервер. Адрес сервера, имя отправителя и включённая или выключенная отправка — параметры. А правило «после подтверждения заказа отправить письмо с составом покупки» — поведение, которому место в коде.
Физическое расположение значения само по себе ничего не решает. Константа в файле, который меняют перед каждым запуском, фактически работает как конфигурация, только с неудобной доставкой. И наоборот: переменная окружения, которая включает одну из нескольких тщательно проверенных реализаций, может быть частью управления поведением, а не просто настройкой.
Хорошая конфигурация меняет параметры уже предусмотренного поведения. Если для каждого значения приходится заново объяснять, что именно теперь делает продукт, перед вами, скорее всего, новое правило, а не настройка.
Проверка из четырёх вопросов
Перед тем как вынести значение из кода, ответьте на четыре вопроса. Вместе они показывают, кому принадлежит изменение и какую страховку нужно поставить.
- Кто вправе менять значение? Если это разработчик при выпуске новой версии, значение может быть частью кода. Если оператор меняет его при развёртывании — это кандидат в конфигурацию. Если значение меняет сотрудник поддержки или клиент — нужны отдельные права, интерфейс и аудит.
- Как часто оно меняется? Редко меняющийся технический порог проще контролировать вместе с кодом. Часто меняющиеся параметры окружения — например адрес внешнего сервиса — удобнее задавать отдельно. Но частота сама по себе не превращает бизнес-правило в настройку.
- Нужно ли проверять изменение до применения? Если значение влияет на оплату, доступы или отправку данных, менять его как произвольную строку опасно. Нужны проверка допустимых значений, согласование и возможность отката.
- Можно ли понять причину изменения? Для конфигурации должны быть известны автор, время и прежнее значение. Если этого нет, расследование превращается в угадайку: «на сервере вроде поменяли переменную».
Практический критерий: если изменение должно проходить код-ревью, тесты и релиз, держите правило в коде. Если оно выбирает окружение или регулирует уже предусмотренный параметр, храните его отдельно — но под контролем версий или аудита.
Что вы выигрываете и чем платите
| Подход | Что удобно | Цена и риск | Когда подходит |
|---|---|---|---|
| Значение в коде | Изменение видно в коммите, проходит обычные проверки и попадает в выпуск вместе с поведением | Небольшую настройку нельзя поменять независимо от релиза | Бизнес-правила, алгоритмы, значения, которые должны меняться только с проверкой приложения |
| Конфигурация окружения | Разные адреса сервисов и параметры запуска можно задать отдельно для разработки, тестирования и эксплуатации | Ошибка в окружении может остаться невидимой в репозитории; секреты можно случайно раскрыть через логи или диагностику | Параметры развёртывания, подключения и режимы запуска |
| Управляемый переключатель функции | Можно включать уже реализованную функцию для выбранной группы или поэтапно | Появляются состояния, которые надо тестировать, журналировать и впоследствии очищать | Контролируемое включение готовой функции с назначенным владельцем и сроком удаления переключателя |
Под переключателем функции здесь понимается управляемое условие, которое включает или отключает уже написанную возможность. Это не универсальная отговорка, позволяющая сложить в конфигурацию все незаконченные решения. Чем больше таких переключателей, тем больше сочетаний поведения; проверка каждой комбинации быстро становится отдельной задачей.
Пограничные случаи: лимиты, флаги и тексты
Таймауты и лимиты
Таймаут запроса или максимальный размер загружаемого файла часто зависят от окружения и нагрузки. Их разумно вынести в конфигурацию, если приложение умеет проверить допустимый диапазон и безопасно вести себя при ошибочном значении. Если лимит отражает продуктовую политику — например, кому доступна загрузка и какого объёма, — изменение уже затрагивает правило. Его нужно согласовать с владельцем продукта, а не оставлять на усмотрение того, кто редактирует окружение.
Переключатели функций
Флаг полезен, когда функцию нужно включить без повторной сборки или сначала показать ограниченной группе. Но у него должны быть владелец, назначение и условие удаления. Иначе через несколько месяцев никто не знает, какие значения допустимы и можно ли убрать старую ветку. Проверяйте не только включённое состояние: при выключенной функции приложение тоже должно корректно запускаться и обрабатывать уже созданные данные.
Тексты и локализация
Надпись на кнопке можно вынести в ресурсный файл, потому что интерфейс может поддерживать разные языки. Но если от текста зависит смысл согласия, условия продажи или юридически значимое уведомление, его изменение нельзя считать безобидной настройкой. Нужны владелец, проверка содержания и история версий.
Где подход ломается
- Конфигурация без проверки. Пустой адрес сервиса или строка вместо числа обнаруживаются в самый неудобный момент. Проверяйте обязательные значения и диапазоны при запуске, а сообщение об ошибке делайте понятным.
- Один файл для всех окружений. Так легко отправить тестовый адрес сервиса в эксплуатацию. Разделяйте значения окружений, а секреты храните в предназначенном для них хранилище, не в репозитории.
- Изменение без аудита. Если параметр можно поменять вручную, зафиксируйте автора, время и предыдущее значение. Для критичных изменений добавьте согласование и план отката.
- Секреты в диагностике. При старте приложение может печатать конфигурацию для отладки. Исключите из таких сообщений пароли, токены и ключи; маскировка должна работать и в логах ошибок.
- Бесконечные временные флаги. Ведите список переключателей с владельцем и датой пересмотра. Если флаг больше не нужен, удалите его вместе с неиспользуемой веткой и тестами.
Как выбрать границу в проекте
Для каждого спорного значения запишите, кто его меняет, когда изменение должно вступить в силу и как его откатить. Затем отнесите его к одному из трёх вариантов:
- Код — если это логика, продуктовая политика или изменение, требующее тестов и релиза.
- Конфигурация окружения — если это параметр подключения или запуска, различающийся между средами.
- Управляемая настройка — если значение меняет уполномоченный человек во время работы системы; тогда нужны интерфейс или регламент, права доступа, аудит и проверки допустимых значений.
Не переносите настройку в отдельное хранилище только ради обещания «менять без релиза». Если цена ошибки высока, возможность менять быстрее имеет смысл лишь вместе с контролем и откатом. Для технических параметров начните с проверки поведения на тестовой среде; для продуктовых правил — с согласования владельца, который отвечает за последствия.
Версионная оговорка: это архитектурный разбор, а не инструкция для конкретной версии фреймворка или платформы. Способ доставки конфигурации зависит от стека; проверяйте его по документации используемых инструментов. Подробно выбирать хранилище секретов и проектировать систему флагов здесь не будем — это отдельные задачи.
Что делать дальше
Возьмите несколько наиболее рискованных настроек вашего сервиса и составьте для каждой короткую карточку: назначение, допустимые значения, владелец, способ изменения, аудит и откат. Затем проверьте три сценария на тестовой среде: значение некорректно, настройка случайно изменена, сервис возвращён к прежнему значению. Если команда не может быстро ответить, кто и почему менял параметр, первым шагом сделайте аудит изменений, а не добавляйте новые переключатели.
Инфобез и 152-ФЗ: Аудит политик конфиденциальности, правила сбора cookie.
Спросить за 20 ₽Источники: The Twelve-Factor App: Config, Kubernetes documentation: ConfigMaps
Частые вопросы
Любую настройку, которую нужно менять без релиза, следует вынести из кода?
Можно ли держать конфигурацию в репозитории?
Что делать, если настройку поменяли неправильно?
Переключатель функции — это конфигурация или код?
Как понять, что параметр уже пора зашить в код?
Есть ли универсальный формат или способ хранения конфигурации?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.