Nodejs

 

 

1. Notification  프로젝트 구성 개요

  • 주요 기능: Notification 생성, 전송 상태 관리

 

 

2. 디렉토리 구조 (일부)

project-root/
├── apps/
│   └── notification/        # Notification 마이크로서비스 소스코드
│       ├── main.ts          # 앱 진입점
│       ├── app.module.ts    # 루트 모듈
│       └── notification/    # 도메인 모듈 (엔티티, 서비스 등)
│           └── notification.entity.ts
├── libs/                    # (필요시 공유 모듈 위치)
├── Dockerfile               # NestJS 앱을 위한 Docker 설정
├── docker-compose-notification.yml  # Notification 서비스 전용 컴포즈 파일
├── pnpm-lock.yaml
├── package.json
├── .env                     # 환경 변수 정의 파일
└── tsconfig.json

이 구조는 Monorepo 기반 NestJS 프로젝트에서 흔히 사용하는 구성입니다.

 

3. 환경설정 파일: .env

.env 파일은 앱의 환경 변수들을 설정해주는 핵심 파일입니다.

HTTP_PORT=3005
DB_URL=mongodb://mongo:mongo@mongo_notification:27017/notification?authSource=admin&retryWrites=true&w=majority
JWT_SECRET=your-secret-key
ACCESS_TOKEN_SECRET=your_access_token_secret
REFRESH_TOKEN_SECRET=your_refresh_token_secret

로컬에서 테스트할 경우 DB_URL을 localhost로 교체할 수 있습니다.

 

 

4.  Dockerfile

NestJS Notification 앱을 컨테이너로 빌드하기 위한 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/notification apps/notification

RUN pnpm build notification

CMD ["pnpm", "start:dev", "notification"]

apps/notification 경로에 프로젝트 소스가 위치합니다.

 

 

5. docker-compose-notification.yml: 컴포즈 설정

docker-compose-notification.yml은 Notification 마이크로서비스와 MongoDB를 함께 실행하기 위한 설정입니다.

services:

  notification:
    build:
      context: .
      dockerfile: ./apps/notification/Dockerfile
      target: development
    command: pnpm run start:dev notification
    depends_on:
      mongo_notification:
        condition: service_healthy
    env_file:
      - ./apps/notification/.env
    ports:
      - '3005:3005'  
    volumes:
      - .:/usr/src/app
      - /usr/src/app/node_modules

  mongo_notification:
    image: mongo:8
    environment:
      MONGO_INITDB_ROOT_USERNAME: mongo
      MONGO_INITDB_ROOT_PASSWORD: mongo
    ports:
      - '6005:27017'
    volumes:
      - ./mongo/notification:/data/lib
    command: mongod --quiet --logpath /dev/null
    healthcheck:
      test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 5s

실행 명령어:

docker-compose -f docker-compose-notification.yml build --no-cache
docker-compose -f docker-compose-notification.yml up -d --remove-orphans
docker-compose -f docker-compose-notification.yml logs -f notification

 

6. 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 ?? 3005);
}
bootstrap();

.env의 HTTP_PORT가 대문자임을 감안하면 process.env.HTTP_PORT로 참조해야 합니다.

 

 

 

7. app.module.ts: 루트 모듈 구성

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as Joi from 'joi';
import { MongooseModule } from '@nestjs/mongoose';
import { NotificationModule } from './notification/notification.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: Joi.object({
        HTTP_PORT: Joi.number().required(),
        DB_URL: Joi.string().required(),
      }),
    }),
    MongooseModule.forRootAsync({
      useFactory: (configService: ConfigService) => ({
        uri: configService.getOrThrow('DB_URL'),
      }),
      inject: [ConfigService],
    }),
    NotificationModule,
  ],
})
export class AppModule {}

ConfigModule과 Joi를 통해 환경 변수의 유효성을 검증합니다.

 

 

 

8. notification.entity.ts: Mongoose 스키마 정의

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

export enum NotificationStatus {
  pending,
  sent,
}

@Schema()
export class Notification extends Document {
  @Prop({ required: true })
  from: string;

  @Prop({ required: true })
  to: string;

  @Prop({ required: true })
  subject: string;

  @Prop({ required: true })
  content: string;

  @Prop({
    enum: NotificationStatus,
    default: NotificationStatus.pending,
  })
  status: NotificationStatus;
}

export const NotificationSchema = SchemaFactory.createForClass(Notification);

from, to, subject, content, status 필드를 갖는 스키마입니다. 기본 상태는 pending으로 설정됩니다.

status는 enum 타입을 사용해 상태(pending/sent)를 명확히 구분합니다.

이는 MongoDB에 저장될 Notification 문서의 명세(schema) 역할을 하며, 타입 안정성과 데이터 유효성을 보장합니다.

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

모든 살아있는 생물은 고통과 죽음을 두려워한다. 피조물을 학대하지 말고 죽이지도 말고 하루도 빠지지 않고 이해하도록 노력해라. 나 이외의 모든 살아있는 생물도 내가 원하는 것을 원하며 자신의 목숨을 최고로 여긴다. -불교

댓글 ( 0)

댓글 남기기

작성