모듈도 하나의 프로젝트처럼 생겼는데, 어떻게 관리하는게 좋을까?
서브모듈이란,
Git 저장소 안에 다른 Git 저장소를 디렉토리로 분리해 넣는 것이 서브모듈이다. 다른 독립된 Git 저장소를 Clone 해서 내 Git 저장소 안에 포함할 수 있으며 각 저장소의 커밋은 독립적으로 관리한다.
각 모듈별 의존성을 최소화하여 MSA 구성 시, 빠르게 구성할 수 있도록 하는 것
export interface ProductService {
getProduct(input: getProductDto): Promise<ProductResponse>;
}
@Injectable()
export class LocalProductServiceImpl implements ProductService {
constructor(private readonly repo: ProductRepository) {}
async getProduct(input: getProductDto): Promise<ProductResponse> {
// 내부 도메인 로직 실행
}
}
@Injectable()
export class GrpcProductServiceImpl implements ProductService {
constructor(@Inject(GRPC_CLIENT) private client: ProductGrpcClient) {}
async getProduct(input: getProductDto): Promise<ProductResponse> {
return this.client.getProduct(input); // gRPC 호출
}
}
// order/order.module.ts
@Module({
providers: [
{
provide: ProductService,
useClass: LocalProductServiceImpl, // 해당영역 gRPC로 수정
},
],
exports: [OrderService],
})
export class OrderModule {}
src/
├── order/
│ ├── application/
│ │ └── order.service.ts
│ ├── domain/
│ └── order.module.ts
│
├── member/
│ ├── application/
│ │ └── member.service.ts
│ └── member.module.ts
│
├── shared/
│ ├── adapters/
│ │ ├── member/
│ │ │ ├── grpc-member.service.ts
│ │ │ └── local-member.service.ts
│ │ └── order/
│ │ ├── grpc-order.service.ts
│ │ └── local-order.service.ts
│ ├── interfaces/
│ │ ├── member.service.interface.ts
│ │ └── order.service.interface.ts
│ └── domain/
│ └── proto/
│ └── order.proto
// src/member/member.module.ts
import { Module } from '@nestjs/common';
import { MemberService } from './application/member.service';
import { OrderService } from '../shared/interfaces/order.service.interface';
import { LocalOrderService } from '../shared/adapters/order/local-order.service';
// import { GrpcOrderService } from '../shared/adapters/order/grpc-order.service';
import { OrderModule } from '../order/order.module';
@Module({
imports: [OrderModule],
providers: [
MemberService,
{
provide: OrderService,
useClass: process.env.USE_GRPC === 'true' ? GrpcOrderService : LocalOrderService,
},
],
})
export class MemberModule {}
order-service/
├── src/
│ ├── order/
│ │ ├── order.controller.ts
│ │ ├── order.service.ts
│ │ └── ...
│ └── member/
│ ├── grpc-member.service.ts ✅
│ └── member.service.interface.ts
├── proto/
│ └── member.proto ✅
order-service/
├── package.json // depends on: "@company/member-client"
그리고 MSA 구성을 준비할 때에도 각각의 서비스별 gRPC Client 는 어찌됐던 중복되기 마련이다.
import { Module } from '@nestjs/common';
import { TestCommerceService } from './test-commerce.service';
import { TestCommerceController } from './test-commerce.controller';
@Module({
controllers: [TestCommerceController],
providers: [TestCommerceService], // 각 타 모듈 서비스 주입
})
export class TestCommerceModule {}