foundation
Configuration
Загружайте configuration детерминированно, валидируйте at startup, отделяйте config от secrets и задавайте safe defaults.
Конфигурация меняется между окружениями, но не между артефактами деплоя — загрузите один раз при старте, проверьте форму, инжектируйте в модули вместо чтения env по всему коду.
import { z } from 'zod';
const ConfigSchema = z.object({
port: z.coerce.number().default(3000),
databaseUrl: z.string().url(),
logLevel: z.enum(['debug', 'info', 'warn']).default('info'),
});
export const config = ConfigSchema.parse({
port: process.env.PORT,
databaseUrl: process.env.DATABASE_URL,
logLevel: process.env.LOG_LEVEL,
});
Fail fast: неверный config не должен слушать порт. Секреты отдельно от обычного config — другой цикл ротации и доступ.
12-factor: config в environment, парсинг — в одном модуле. Не размазывайте `process.env.FEATURE_X` по бизнес-логике.
На интервью: валидация при старте; feature flags vs config; тесты без глобального env.
Типовые ошибки: тихие default скрывают ошибку; разные пути config dev/prod; секреты в файлах образа.
Компромисс — между простотой, производительностью, безопасностью и эксплуатацией: назовите, что оптимизировали и какую цену приняли.
Чеклист:
- Один readonly config-модуль.
- Схема при boot.
- Документация обязательных переменных.
- Неизменяемость после инициализации.