Service가 DB 구현 대신 업무 저장소 계약에 의존하게 합니다.
Repository interface와 token으로 업무 계층을 특정 ORM에서 분리합니다. adapter가 DB row와 domain 데이터를 변환합니다.
트랜잭션 context가 필요한 작업은 계약에 명시적으로 전달하거나 unit of work를 설계합니다.
ORM entity를 Controller 응답에 그대로 노출하지 않습니다.
범용 repository 하나에 모든 query를 넣으면 업무 의도가 사라집니다.
로컬 프로젝트에서 확인해보세요findById와 중복 title 검사 메서드를 추가하세요.
import "reflect-metadata";
import { Controller, Get, Inject, Injectable, Module } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
const REPO = Symbol("CourseRepository");
class MemoryRepo {
findPublished() {
return [{ id: 1, title: "Nest Adapter" }];
}
}
@Injectable()
class CourseService {
constructor(@Inject(REPO) private readonly repo: MemoryRepo) {}
list() {
return this.repo.findPublished();
}
}
@Controller()
class AppController {
constructor(private readonly service: CourseService) {}
@Get() home() {
return this.service.list();
}
}
@Module({
controllers: [AppController],
providers: [CourseService, { provide: REPO, useClass: MemoryRepo }],
})
class AppModule {}
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(4173, "0.0.0.0");
}
bootstrap();