programing

NestJS 모듈에서 구성 서비스를 사용하는 모범 사례

minimums 2023. 7. 12. 23:39
반응형

NestJS 모듈에서 구성 서비스를 사용하는 모범 사례

하여 환경변사다구성합다니음을용여하를 .HttpModule모듈별로 문서에서 다음과 같은 구성을 사용할 수 있습니다.

@Module({
  imports: [HttpModule.register({
    timeout: 5000,
    maxRedirects: 5,
  })],
})

하지만 기지를 포함하는 최선의 방법이 무엇인지 모르겠습니다.사용 가능한 환경(또는 구성 서비스)의 URL(예:

@Module({
imports: [HttpModule.register({
    baseURL:  this.config.get('API_BASE_URL'),
    timeout: 5000,
    maxRedirects: 5,
})],

this.config이라undefined수업 외니까 여기.

기준을 설정하는 가장 좋은 방법은 무엇입니까?환경 변수(또는 구성 서비스)의 URL?

1월 19일 업데이트

HttpModule.registerAsync() 요청과 함께 버전 5.5.0에 추가되었습니다.

HttpModule.registerAsync({
  imports:[ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    baseURL:  configService.get('API_BASE_URL'),
    timeout: 5000,
    maxRedirects: 5,
  }),
  inject: [ConfigService]
}),

원본 게시물

이 문제는 이번 호에서 논의되었습니다.다음과 같은 nestjs 모듈의 경우TypeOrmModule 는또.MongooseModule다음 패턴이 구현되었습니다.

useFactorymethod는 구성 개체를 반환합니다.

TypeOrmModule.forRootAsync({
  imports:[ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    type: configService.getDatabase()
  }),
  inject: [ConfigService]
}),

카밀이 썼지만,

이제 위의 규칙이 모든 최신 모듈에 적용되며 모범 사례(+타사 모듈 권장 사항)로 간주됩니다.문서에서 더 보기

그것은 그것을 위해 구현되지 않은 것으로 보입니다.HttpModule아직, 하지만 당신은 그것에 대한 이슈를 열 수 있을 것입니다.위에서 언급한 이슈에 대한 다른 제안들도 있습니다.

또한 모범 사례가 포함된 공식 문서를 살펴봅니다.ConfigService.

구현에 는 이질에대최답대구의대정만기지확로하, 용는자사으적을 사용합니다.@nestjs/typeorm패지고, 리그키고TypeOrmModule아래와 같은 구현을 사용해야 합니다.

// NestJS expects database types to match a type listed in TypeOrmModuleOptions
import { TypeOrmModuleOptions } from '@nestjs/typeorm/dist/interfaces/typeorm-options.interface';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [mySettingsFactory],
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        type: configService.get<TypeOrmModuleOptions>('database.type', {
          infer: true, // We also need to infer the type of the database.type variable to make userFactory happy
        }),
        database: configService.get<string>('database.host'),
        entities: [__dirname + '/**/*.entity{.ts,.js}'],
        synchronize: true,
        logging: true,
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [],
})
export class AppRoot {
  constructor(private connection: Connection) {}
}

이 코드가 수행하는 주요 작업은 TypeORM에서 올바른 유형을 검색하고(가져오기 참조) 이를 사용하여 반환 값 configService.get() 메서드를 힌트로 제공하는 것입니다.올바른 TypeORM 타이핑을 사용하지 않으면 Type스크립트가 화를 낼 수 있습니다.

또한 구축 과정에서 몇 가지 문제가 발생했습니다.ConfigServiceNestJS 문서에 설명된 바와 같이(유형 안전성, 구성 값 모듈화 없음 등) 당사의 최종 Nest를 기록했습니다.JS 구성 관리 전략에 대한 자세한 내용은 다음을 참조하십시오. NestJS 구성 관리

기본 아이디어는 프로세스의 환경에서 모든 구성 값을 로드하는 중앙 구성 모듈을 갖는 것입니다.그러나 모든 모듈에 단일 서비스를 제공하는 대신 각 모듈은 구성 값의 전용 하위 집합을 주입할 수 있습니다!따라서 각 모듈에는 이 모듈이 런타임에 제공되어야 하는 모든 구성 값을 지정하는 클래스가 포함되어 있습니다.이와 동시에 개발자는 코드베이스 전체에서 문자열 리터럴을 사용하는 대신 구성 값에 안전하게 액세스할 수 있습니다.

이 패턴이 당신의 사용 사례에도 효과가 있기를 바랍니다 :)

@Kim Kern의 훌륭한 답변은 분명히 주입을 넘어갑니다.ConfigService환경 변수에 따라 달라질 수 있는 모듈 구성입니다. 하지만 제 개인적인 경험으로 볼 때, 앱 루트 모듈이나 몇 가지 가져오기 기능이 있는 다른 모듈은 읽기가 어렵고 가져오기 기능, 모듈 구성 및 정의하는 모듈이 무엇인지 이해하기 어려울 수 있습니다.그래서, 이 질문에 대해 저를 큐레이팅해주신 제이 맥도니얼 덕분에,you can move configuration logic into a separate file.



첫 번째 솔루션


의 예app.module.ts:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { MikroOrmModule } from '@mikro-orm/nestjs';

import { AppService } from './users.service';
import { AppController } from './users.controller';
import { get_db_config } from './config/database.config';

@Module({
    imports:     [
        ConfigModule.forRoot({ 
            isGlobal:        true, 
            expandVariables: true,
        }),

        MikroOrmModule.forRootAsync( get_db_config() ),
    ],
    controllers: [AppController],
    providers:   [AppService],
})
export class AppModule {}

의 예config/database.config.ts:

import { MikroOrmModuleAsyncOptions } from "@mikro-orm/nestjs";
import { ConfigService } from "@nestjs/config";


export function get_db_config(): MikroOrmModuleAsyncOptions
{
    return {
        useFactory: (configService: ConfigService) => 
        ({
            dbName:          'driver',
            type:            'postgresql',
            host:             configService.get('DB_HOST'),
            port:             configService.get('DB_PORT'),
            user:             configService.get('DB_USERNAME'),
            password:         configService.get('DB_PASSWORD'),
            autoLoadEntities: true
        }),
        inject: [ConfigService]
    }
}



그러나 NestJS Docs - Configuration Namespaces 및 NestJS Authentication and Authorization Course는 이 문제를 해결하는 대체 방법을 제공합니다.



세컨드 솔루션


의 예auth.module.ts:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';

import jwtConfig from './jwt.config';


@Module({
    imports: [
        ConfigModule.forFeature( jwtConfig ),
        JwtModule.registerAsync( jwtConfig.asProvider() ),
    ]
})
export class AuthModule {}

의 예jwt.config.ts:

import { registerAs } from "@nestjs/config"


export default registerAs('jwt', () => {
    return {
        secret:         process.env.JWT_SECRET,
        issuer:         process.env.JWT_TOKEN_ISSUER,
        accessTokenTtl: parseInt(process.env.JWT_TOKEN_TTL)
    };
});

언급URL : https://stackoverflow.com/questions/53426486/best-practice-to-use-config-service-in-nestjs-module

반응형