본문 바로가기
개발/Nest.js

Nest.js interface 구현체에 DI 적용하기

by jeounpar 2023. 3. 13.

Nest.js 에서 interface는 컴파일 환경에서만 존재하고 런타임 환경에서는 사라지기 때문에 interface를 구현한 클래스는 Nest.js의 DI컨테이너가 해당 컨테이너를 찾지 못한다.

 

해결방법

// test.interface.ts
export interface Test {
  getHello(): string;
}
// test-impl.service.ts
import { Injectable } from '@nestjs/common';
import { Test } from './test.interface';

@Injectable()
export class TestImpl implements Test {
  getHello(): string {
    return 'Hello World!';
  }
}
// app.service.ts
import { Inject, Injectable } from '@nestjs/common';
import { Test } from './test.interface';

@Injectable()
export class AppService {
  constructor(
    @Inject('TestService')
    private readonly testService: Test,
  ) {}

  getHello(): string {
    return this.testService.getHello();
  }
}
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TestImpl } from './test-impl.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, { provide: 'TestService', useClass: TestImpl }],
})
export class AppModule {}
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

npm run start:dev

Postman 테스트

작동이 잘 되는 것을 볼 수 있다.

 

이번에는 Test interface의 구현체를 바꿔보자

// bye-impl.service.ts
import { Injectable } from '@nestjs/common';
import { Test } from './test.interface';

@Injectable()
export class ByeImpl implements Test {
  getHello(): string {
    return 'Bye World!';
  }
}
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ByeImpl } from './bye-impl.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, { provide: 'TestService', useClass: ByeImpl }],
})
export class AppModule {}

 

클라이언트 코드(Service)의 변경이 일어나지 않고 Config(app.module.ts)에서 useClass를 ByeImpl로 교체했다.

Postman 테스트

앞으로 구현 객체가 바뀐다면 app.module.ts에서 useClass 부분만 변경해 주면 될 듯!

코드 : https://github.com/jeounpar/nestjs-interface-di