Что такое ConfigModule и ConfigService в NestJS?
ConfigModule и ConfigService в NestJS
При разработке приложений на NestJS часто требуется хранить чувствительные данные (ключи API, параметры базы данных, секреты) вне исходного кода — в переменных окружения. Пакет @nestjs/config предоставляет удобный способ работы с такими переменными.
ConfigModule
ConfigModule — это модуль, который нужно зарегистрировать в AppModule. Он отвечает за:
- Загрузку переменных из
.env-файла с помощью библиотекиdotenvпод капотом - Их разбор и помещение в глобальный контекст приложения
- Опциональную валидацию через
Joiилиclass-validator
Чаще всего его подключают с опцией isGlobal: true, чтобы не импортировать его заново в каждом модуле.
// app.module.ts
ConfigModule.forRoot({
isGlobal: true, // доступен во всех модулях без повторного импорта
envFilePath: '.env',
})
ConfigService
ConfigService — это инжектируемый сервис, предоставляющий доступ к переменным окружения. Вместо прямого обращения к process.env рекомендуется использовать именно его, поскольку:
- Он поддерживает типизацию через дженерики
- Позволяет задать значение по умолчанию вторым аргументом
- Упрощает тестирование (можно замокать сервис)
// database.service.ts
@Injectable()
export class DatabaseService {
constructor(private readonly configService: ConfigService) {}
getConnectionString(): string {
const host = this.configService.get<string>('DB_HOST', 'localhost');
const port = this.configService.get<number>('DB_PORT', 5432);
return `postgres://${host}:${port}`;
}
}
Пространства имён (namespaces)
Для крупных приложений переменные можно группировать через фабричные функции конфигурации:
// database.config.ts
export default registerAs('database', () => ({
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT, 10) || 5432,
}));
// database.service.ts
const dbConfig = this.configService.get('database');
console.log(dbConfig.host);
Валидация переменных окружения
Одна из важных возможностей — валидация переменных при старте приложения через Joi:
ConfigModule.forRoot({
validationSchema: Joi.object({
DB_HOST: Joi.string().required(),
DB_PORT: Joi.number().default(5432),
JWT_SECRET: Joi.string().min(16).required(),
}),
})
Если какая-то обязательная переменная отсутствует, приложение выбросит ошибку ещё до запуска — это позволяет поймать проблему на этапе деплоя, а не в рантайме.
Итог
ConfigModule + ConfigService — стандартный способ управления конфигурацией в NestJS-приложениях, который обеспечивает чистую архитектуру, типобезопасность и удобное тестирование.
Что хочет услышать интервьюер
Кандидат знает, что ConfigModule нужно подключать в AppModule через forRoot()
Понимает разницу между прямым использованием process.env и ConfigService
Знает про опцию isGlobal и зачем она нужна
Может объяснить, как получить значение через configService.get() с типизацией и дефолтным значением
Имеет представление о валидации переменных окружения при старте приложения
Пример: Подключение ConfigModule в AppModule
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true, // не нужно импортировать в каждый модуль
envFilePath: '.env', // путь до файла с переменными окружения
}),
],
})
export class AppModule {}
Пример: Использование ConfigService в сервисе
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class AppService {
constructor(private readonly configService: ConfigService) {}
getDatabaseUrl(): string {
// второй аргумент — значение по умолчанию
const host = this.configService.get<string>('DB_HOST', 'localhost');
const port = this.configService.get<number>('DB_PORT', 5432);
const name = this.configService.get<string>('DB_NAME');
return `postgres://${host}:${port}/${name}`;
}
}
Пример: Валидация переменных окружения через Joi
import { ConfigModule } from '@nestjs/config';
import * as Joi from 'joi';
ConfigModule.forRoot({
isGlobal: true,
validationSchema: Joi.object({
DB_HOST: Joi.string().required(),
DB_PORT: Joi.number().default(5432),
JWT_SECRET: Joi.string().min(16).required(),
NODE_ENV: Joi.string()
.valid('development', 'production', 'test')
.default('development'),
}),
// при ошибке валидации приложение не запустится
});
Типичные ошибки
Использование process.env напрямую вместо ConfigService — теряется типизация и возможность мокирования в тестах
Забывают установить isGlobal: true и затем не могут понять, почему ConfigService недоступен в других модулях
Не устанавливают пакет @nestjs/config и путают его со встроенными возможностями NestJS
Хардкодят путь к .env-файлу без учёта разных окружений (dev/prod/test)
Не валидируют переменные окружения, что приводит к трудноотлаживаемым ошибкам в рантайме


