[NestJS] TypeORM 쿼리 포맷팅 적용하기

초롱아귀·2025년 4월 29일

NestJS

목록 보기
9/9
post-thumbnail

1. 쿼리 하이라이팅 적용

app.module.tsTypeOrmModule 설정에서 logging 옵션을 활성화 한다.

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: Joi.object({
        // ...
      }),
    }),
    TypeOrmModule.forRootAsync({
      useFactory: (configService: ConfigService) => ({
        type: configService.get<string>(envVariables.dbType) as 'postgres',
        	// ...
        logging: true, // logging 활성화 
      }),
      inject: [ConfigService],
    }),
    // ...
  ],
  providers: [
    // ...
  ],
})
/* 전역 Middleware 설정 */
export class AppModule implements NestModule {
  // ...
}

하이라이팅이 적용된 쿼리를 확인할 수 있다.

2.쿼리 포맷팅 적용과정

2-1. default logger 의 문제점

위와 같이 짧은 쿼리들이면 보고 확인하는데 어려움이 없지만,
아래와 같이 쿼리가 길어질 경우 쿼리를 확인하기 불편했음.

2-2. format 을 적용해주는 옵션은 존재하지 않음

  • 공식문서 에서 default logger 를 변경하는 방법과, 제공하는 4가지 타입의 logger option 을 확인했지만,
    쿼리를 포맷팅 해주는 옵션은 존재하지 않는걸 확인함

3. custom logger 와 sql-formatter 를 사용하여 쿼리 포맷팅 적용

3-1. 라이브러리 설치

쿼리 포맷팅을 위해 sql-formatter 를 의존성에 추가한다.

pnpm add sql-formatter

3-2. custom logger 생성

import { AdvancedConsoleLogger, QueryRunner } from 'typeorm';
import { format as sqlFormat } from 'sql-formatter';

export class FormattedLogger extends AdvancedConsoleLogger {
  constructor(
    options?:
      | boolean
      | 'all'
      | (
          | 'query'
          | 'error'
          | 'schema'
          | 'warn'
          | 'info'
          | 'log'
          | 'migration'
        )[],
  ) {
    /* 기본값 -> query, error 지정 */
    super(options ?? ['query', 'error']);
  }

  override logQuery(
    query: string,
    parameters?: any[],
    queryRunner?: QueryRunner,
  ): void {
    /* 들여쓰기 & 개행 적용 */
    const formatted = sqlFormat(query, { language: 'postgresql' });

    super.logQuery(formatted, parameters, queryRunner);
  }

  override logQueryError(
    error: string | Error,
    query: string,
    parameters?: any[],
    queryRunner?: QueryRunner,
  ): void {
    const formatted = sqlFormat(query, { language: 'postgresql' });
    const errorMessage =
      typeof error === 'string'
        ? error
        : error instanceof Error
          ? error.message
          : String(error);
    super.logQueryError(errorMessage, formatted, parameters, queryRunner);
  }

  override logQuerySlow(
    time: number,
    query: string,
    parameters?: any[],
    queryRunner?: QueryRunner,
  ): void {
    const formatted = sqlFormat(query, { language: 'postgresql' });
    super.logQuerySlow(time, formatted, parameters, queryRunner);
  }
}

3-3. custom logger 적용

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: Joi.object({
        // ...
      }),
    }),
    TypeOrmModule.forRootAsync({
      useFactory: (configService: ConfigService) => ({
        type: configService.get<string>(envVariables.dbType) as 'postgres',
        	// ...
        logging: true,
        logger: new FormattedLogger(), // <- 기본값: ['query', 'error']
      }),
      inject: [ConfigService],
    }),
    // ...
  ],
  providers: [
    // ...
  ],
})
/* 전역 Middleware 설정 */
export class AppModule implements NestModule {
  // ...
}

포맷팅이 적용된 모습

4. 반가운 소식(앞으로 추가될 기능?)

문제해결을 위해 TypeORM GitHub 을 뒤적거리다 반가운 커밋 내용을 발견했다.

2주전에 새로 올라온 FormattedConsoleLogger 커밋 내용

내용을 보면, logger: formatted-console 옵션을 통해 간편하게 쿼리에 포맷팅을 적용해준다.
2주전에 올라온 커밋인데 master 브랜치에 있는것을 보니,
아마 Typeorm 의 다음버전( 0.3.23 )에 적용되지 않을까 기대해본다.

profile
저아닙니다

0개의 댓글