nest g app 설치
1. Docker Compose 설정 (docker-compose-payment.yml)
먼저 Payment 마이크로서비스를 위한 독립된 Docker Compose 파일을 작성합니다.
services: payment: build: context: . dockerfile: ./apps/payment/Dockerfile target: development command: pnpm run start:dev payment depends_on: postgres_payment: condition: service_healthy env_file: - ./apps/payment/.env ports: - '3004:3004' volumes: - .:/usr/src/app - /usr/src/app/node_modules postgres_payment: image: postgres:16 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres ports: - '6004:5432' volumes: - ./postgres/payment:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 10 start_period: 5s
설명:
payment 서비스는 NestJS 애플리케이션을 실행하며, pnpm으로 시작됩니다.
postgres_payment는 해당 서비스만을 위한 전용 PostgreSQL 컨테이너입니다.
healthcheck 설정을 통해 DB가 준비될 때까지 대기합니다.
2. Dockerfile 설정 (apps/payment/Dockerfile)
NestJS 애플리케이션을 빌드하고 실행하기 위한 Dockerfile입니다.
FROM node:alpine AS development WORKDIR /usr/src/app COPY package*.json ./ COPY pnpm-lock.yaml ./ COPY tsconfig.json tsconfig.json COPY nest-cli.json nest-cli.json RUN npm i -g pnpm RUN pnpm i COPY apps/payment apps/payment RUN pnpm build payment CMD ["pnpm", "start:dev", "payment"]
설명:
node:alpine 경량 이미지를 기반으로 빌드합니다.
pnpm을 사용해 의존성을 설치하고, payment 앱을 빌드합니다.
3. 애플리케이션 모듈 구성
app.module.ts
import { Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import * as Joi from 'joi'; import { PaymentModule } from './payment/payment.module'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, validationSchema: Joi.object({ HTTP_PORT: Joi.number().required(), DB_URL: Joi.string().required(), }), }), TypeOrmModule.forRootAsync({ useFactory: (configService: ConfigService) => ({ type: 'postgres', url: configService.getOrThrow('DB_URL'), autoLoadEntities: true, synchronize: true, }), inject: [ConfigService], }), PaymentModule, ], }) export class AppModule {}
설명:
.env 파일의 유효성을 Joi로 검증합니다.
TypeORM 설정을 비동기로 주입받으며, DB_URL 환경변수로 DB 연결을 설정합니다.
PaymentModule을 import하여 결제 관련 기능을 모듈화합니다.
4. 앱 진입점 구성 (main.ts)
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(process.env.HTTP_PORT ?? 3004); } bootstrap();
설명:
환경 변수 HTTP_PORT가 없으면 기본값 3004에서 서버를 실행합니다.
5. Payment 모듈 구성
payment.module.ts
import { Module } from '@nestjs/common'; import { PaymentController } from './payment.controller'; import { PaymentService } from './payment.service'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Payment } from './payment.entity'; @Module({ imports: [TypeOrmModule.forFeature([Payment])], controllers: [PaymentController], providers: [PaymentService], }) export class PaymentModule {}
설명:
해당 모듈은 단일 책임 원칙을 지키며, 결제 관련 컨트롤러/서비스를 포함합니다.
TypeOrmModule.forFeature로 Payment 엔티티를 모듈에 등록합니다.
6. Payment Entity 구성
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; export enum PaymentStatus { pending = 'Pending', rejected = 'Rejected', approved = 'Approved', } export enum PaymentMethod { creditCard = 'CreditCard', kakao = 'Kakao', } export enum NotificationStatus { pending = 'pending', sent = 'sent', } @Entity() export class Payment { @PrimaryGeneratedColumn('uuid') id: string; @Column({ enum: PaymentStatus, type: 'enum', default: PaymentStatus.pending, }) paymentStatus: PaymentStatus; @Column({ enum: PaymentMethod, type: 'enum', default: PaymentMethod.creditCard, }) paymentMethod: PaymentMethod; @Column() cardNumber: string; @Column() expiryYear: string; @Column() expiryMonth: string; @Column() birthOrRegistration: string; @Column() passwordTwoDigits: string; @Column({ enum: NotificationStatus, type: 'enum', default: NotificationStatus.pending, }) notificationStatus: NotificationStatus; }
설명:
Payment 엔티티는 결제 요청 정보를 담고 있으며, 총 3개의 enum 필드를 포함합니다:
paymentStatus: 결제 상태 (Pending, Rejected, Approved)
paymentMethod: 결제 방식 (CreditCard, Kakao)
notificationStatus: 알림 상태 (pending, sent)
카드 정보와 본인 인증 정보도 포함되어 있습니다.
이후 이 엔티티를 기반으로 결제 처리 및 알림 로직이 확장됩니다.
7. Controller / Service 구성
payment.controller.ts
import { Controller, Get } from '@nestjs/common'; import { PaymentService } from './payment.service'; @Controller() export class PaymentController { constructor(private readonly paymentService: PaymentService) {} @Get() getHello(): string { return this.paymentService.getHello(); } }
payment.service.ts
import { Injectable } from '@nestjs/common'; @Injectable() export class PaymentService { getHello(): string { return 'Hello World!'; } }
설명:
현재는 간단한 텍스트(Hello World!)를 반환하지만, 이후 실제 결제 로직으로 확장됩니다.
NestJS의 기본 구조 (Controller -> Service 구조)를 따릅니다.
댓글 ( 0)
댓글 남기기