Search

@nestjs/config의 registerAs

registerAs()란?

NestJS에서 설정 객체를 모듈화하여 ConfigModule에서 쉽게 가져올 수 있도록 도와주는 함수
여러 개의 설정 파일을 만들고 ConfigModule에서 불러올 때 Key를 기반으로 접근할 수 있도록 한다.
// jwt.config.ts import { registerAs } from '@nestjs/config'; export default registerAs('jwt', () => ({ secret: process.env.JWT_SECRET || 'default-secret', // JWT 서명 키 signOptions: { expiresIn: process.env.JWT_EXPIRES_IN || '1h', // JWT 만료 시간 }, }));
TypeScript
복사
‘jwt’라는 key를 설정했으므로 ‘jwt’라는 네임스페이스를 가진 설정 객체가 된다. → jwtConfig로 접근 가능!
app.module.ts에서 configModule.forRoot()load 옵션을 사용하여 위 설정 파일을 불러온다.
// src/app.module.ts import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import jwtConfig from './config/jwt.config'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, // 글로벌 모듈로 등록 load: [jwtConfig], // jwt 설정 파일 로드 }), ], }) export class AppModule {}
TypeScript
복사

새로운 사실

위에서 key값을 설정하면 key값이 네임스페이스로 설정된 설정 객체가 된다고 했다.
ex) ‘abc’ → abcConfig로 접근가능
import jwtAuthConfig from '@/common/config/auth/jwt.auth.config'; @Inject(jwtAuthConfig.KEY) private jwtTokenConfig: ConfigType<typeof jwtAuthConfig>, ---------------------------------------------------------------------------------------------------------- import jwtConfig from '../../config/auth/jwt.auth.config'; @Inject(jwtConfig.KEY) private jwtConfiguration: ConfigType<typeof jwtConfig>, // ConfigType<typeof xxxConfig>로 타입 안정성을 유지하면서 설정을 가져올 수 있다.
TypeScript
복사
그러나 위와같은 문법을 사용하게 되면 key값과 동일한 이름으로 config를 잡지않아도 import로 매핑을 시키면 key값과 다른 이름으로도 설정이 가능하다….
위 두 케이스에서는 서로 다른이름으로 config를 설정하였지만 둘 다 ‘jwt’를 키값으로 설정한 config파일과 연동되어 있다….

jwt 모듈 등록

@Module({ imports: [ JwtModule.register({ secret: process.env.JWT_SECRET, signOptions: { expiresIn: '12h' }, }), HttpModule, PassportModule, // 기본 설정만 등록, 전략은 각별히 등록 ], }), exports: [JwtModule], export class AuthModule {}
TypeScript
복사
위와 같은 방법으로 Jwt모듈을 등록할 수 있다.
하지만 나는 jwtConfig라는 설정 객체를 만들어서 모듈화를 해뒀다.
그렇다면 이렇게 코드를 짤 수도 있다.
@Module({ imports: [ JwtModule.registerAsync(jwtConfig.asProvider()), ConfigModule.forFeature(jwtConfig), HttpModule, PassportModule, ], exports: [JwtModule], }) export class AuthModule {} // jwt.config.ts export default registerAs( 'jwt', (): JwtModuleOptions => ({ secret: process.env.JWT_SECRET, signOptions: { expiresIn: process.env.JWT_EXPIRE_IN, }, }), );
TypeScript
복사
jwtModule.registerAsync(jwtConfig.asProvider()) NestJS에서 JwtModule.register() 를 사용할수도 있지만 환경변수나 설정파일에서 값을 가져와야 하는 경우 비동기 설정방식registerAsync()를 사용한다.
비동기설정
동기적인 방식(static)이 아니라 실행 시점에 동적으로 값을 가져올 수 있도록 한다.
1.
정적 설정 (static)
JwtModule.register({ secret: 'mysecret', signOptions: { expiresIn: '12h' }, }); 장점 : 간단하고 빠르다. 단점 : 환경 변수 또는 외부 시스템에서 값을 가져올 수 없다.
TypeScript
복사
2.
동적 설정 : 실행 시점에 값을 로드할 수 있지만, 비동기 작업은 불가능한 방식
JwtModule.register({ secret: process.env.JWT_SECRET || 'default-secret', signOptions: { expiresIn: process.env.JWT_EXPIRE_IN || '12h' }, }); 장점 : 환경 변수 등 동적으로 값을 설정 가능 단점 : DB 조회나 API 호출처럼 비동기 작업을 수행할 수 없다.
TypeScript
복사
3.
비동기 설정
JwtModule.registerAsync({ imports: [ConfigModule], // ConfigService 사용 가능하도록 설정 inject: [ConfigService], // ConfigService를 주입받음 useFactory: async (configService: ConfigService) => ({ secret: await someAsyncFunction(configService.get('JWT_SECRET')), signOptions: { expiresIn: configService.get('JWT_EXPIRE_IN') || '12h' }, }), }); 장점 : DB 조회나 API 호출처럼 비동기 작업을 수행할 수 있다. 단점 : 코드가 복잡해짐.
TypeScript
복사
jwtConfig.asProvider()
jwt.config.ts에서 registerAs()로 만든 설정을 jwtModule.registerAsync() 에서 사용할 수 있도록 변환하는 함수
registerAs()는 일반적으로 ConfigModule.forFeature()와 함께 사용되지만 asProvider()를 사용하면 해당 설정을 직접 JWT 모듈의 프로바이더로 사용할 수 있다.
export default registerAs( 'jwt', () => ({ secret: process.env.JWT_SECRET, signOptions: { expiresIn: process.env.JWT_EXPIRE_IN || '12h' }, }), ); // `asProvider()`를 사용하면 위 설정을 JwtModule에 직접 넘길 수 있음 // 아래 코드는 위 코드와 동일하게 동작한다. JwtModule.registerAsync(jwtConfig.asProvider()),
TypeScript
복사