2025. 6. 21. 13:00ㆍNode.js
https://developerjjh.tistory.com/212
(Node.js) Nestjs + MSA기반 서버 구축 (2) - MongoDB & Docker 연동
2025.06.05 - [Node.js] - (Node.js) Nestjs + MSA 기반 서버 구축 (1) (Node.js) Nestjs + MSA 기반 서버 구축 (1)● 순서 요지환경 설정 및 Lib 설치코드 구현테스트 통신마무리 1. 요지우연히 NestJS + MSA + MongoDB를 기반
developerjjh.tistory.com
● 순서
- 요지
- 기능 설명
- 예제 코드
- 테스트 통신 결과
- 마무리
1. 요지
이전 게시물에서는 NestJS에 MSA 패턴을 적용한 후 데이터베이스 중 MongoDB를 연동하였다
이제 해당 요청에 따른 기능을 만들어보려고 한다
2. 기능 설명
- 게시물 전체 조회
- 등록되어 있는 모든 게시물을 조회한다
- 게시물 등록
- 게시물의 제목과 내용으로 요청
- 제목은 필수 값이지만 내용은 없어도 등록되도록 설정
- 제목은 중복을 방지
- 게시물 수정
- 게시물의 id값과 수정하고자 하는 내용을 요청
- 해당 id값에 대한 존재여부도 확인하여 유효성 검사를 실시
- 게시물 삭제
- 수정과 마찬가지로 id값으로 삭제하고자 하는 게시물을 삭제
- 존재하지 않는 게시물의 id값으로 요청 시 에러를 반환하도록 한다
3. 예제 코드
gateway controller
- API의 진입점으로 요청의 필수값에 대한 존재 여부를 검사
// gateway/src/app.controller.ts
import {
Controller,
Get,
Post,
Body,
Patch,
Delete,
Param,
} from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
@Get('boards')
async getBoards() {
return this.appService.getBoards();
}
@Post('board')
async createBoard(@Body() data: { title: string; text?: string }) {
if (!data.title) throw new Error('Title is required for creating a board');
return this.appService.createBoard(data);
}
@Patch('board/update/:id')
async updateBoard(
@Param('id') id: string,
@Body() data: { title: string; text?: string },
) {
if (!id || !data.title) {
throw new Error('ID and title are required for updating a board');
}
return this.appService.updateBoard(id, data);
}
@Delete('board/delete/:id')
async deleteBoard(@Param('id') id: string) {
if (!id) throw new Error('ID is required for deleting a board');
return this.appService.deleteBoard(id);
}
}
gateway service
- board 서비스와 TCP 연결 후 일치하는 통신을 요청
// gateway/src/app.service.ts
import { Injectable } from '@nestjs/common';
import {
ClientProxy,
ClientProxyFactory,
Transport,
} from '@nestjs/microservices';
@Injectable()
export class AppService {
private boardClient: ClientProxy;
constructor() {
this.boardClient = ClientProxyFactory.create({
transport: Transport.TCP,
options: { host: '0.0.0.0', port: 4002 },
});
}
getHello(): string {
return 'Hello World!';
}
getBoards() {
return this.boardClient.send({ cmd: 'get-boards' }, {});
}
createBoard(data: any) {
return this.boardClient.send({ cmd: 'create-board' }, data);
}
updateBoard(id: string, data: { title: string; text?: string }) {
return this.boardClient.send({ cmd: 'update-board' }, { id, ...data });
}
deleteBoard(id: string) {
return this.boardClient.send({ cmd: 'delete-board' }, { id });
}
}
board controller
- gateway에서 TCP 통신에 대한 service 메서드를 호출
import { Controller } from '@nestjs/common';
import { MessagePattern, Payload } from '@nestjs/microservices';
import { AppService } from './app.service';
import { Board } from './schema/board.schema';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@MessagePattern({ cmd: 'get-boards' })
getBoards() {
return this.appService.findAll();
}
@MessagePattern({ cmd: 'create-board' })
createBoard(@Payload() data: Partial<Board>) {
return this.appService.create(data);
}
@MessagePattern({ cmd: 'update-board' })
updateBoard(@Payload() data: { id: string; title: string; text?: string }) {
return this.appService.updateBoard(data.id, {
title: data.title,
text: data.text,
});
}
@MessagePattern({ cmd: 'delete-board' })
deleteBoard(@Payload() data: { id: string }) {
return this.appService.deleteBoard(data.id);
}
}
board service
- 각 메서드 별 비즈니스 및 DB 로직을 작성
import { Injectable } from '@nestjs/common';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { Board } from './schema/board.schema';
@Injectable()
export class AppService {
constructor(@InjectModel(Board.name) private boardModel: Model<Board>) {}
async findAll(): Promise<Board[]> {
return this.boardModel.find().exec();
}
async create(data: Partial<Board>): Promise<Board> {
const isBoard = await this.boardModel.findOne({ title: data.title }).exec();
if (isBoard) throw new Error('Board with this title already exists');
if (!data.text) data.text = '';
const createdBoard = new this.boardModel(data);
await createdBoard.save();
return createdBoard;
}
async updateBoard(id: string, data: Partial<Board>): Promise<Board | null> {
const board = await this.boardModel.findById(id).exec();
if (!board) throw new Error('Board not found');
if (data.title) board.title = data.title;
if (data.text) board.text = data.text;
await board.save();
return board;
}
async deleteBoard(id: string): Promise<Board | null> {
const board = await this.boardModel.findByIdAndDelete(id).exec();
if (!board) throw new Error('Board not found');
return board;
}
}
4. 테스트 통신 결과
- 전체 게시물 호출
전체 게시물 호출 - 게시물 등록
게시물 등록 - 특정 게시물 수정
수정 결과 및 수정 후 전체 조회 - 특정 게시물 삭제
5. 마무리
간단하게 최소한의 중복이나 존재 여부 정도만 검사하고 CRUD 하는 과정을 담아봤습니다
아직 부족한 점이 많지만 새로운 패턴과 환경 등을 적용하는 과정이니 참고 정도만 해주시면 감사하겠습니다
다음에는 또 다른 서비스(서버)를 연결하여 더 많은 기능들을 내포하는 프로젝트로 확장하는 게 목적입니다
유저 서비스를 별도로 생성하여서 로그인 상태를 검증하는 거를 생각하고 있으며 더 나아가 권한까지 부여하여 점차 커져가는 게 목표입니다
천천히 과정을 담아 볼테니 많은 관심 부탁드려요!!

'Node.js' 카테고리의 다른 글
(Node.js) Nestjs + MSA기반 서버 구축 (2) - MongoDB & Docker 연동 (0) | 2025.06.11 |
---|---|
(Node.js) Nestjs + MSA 기반 서버 구축 (1) (0) | 2025.06.08 |
(Node.js) nodemailer로 파일첨부 (0) | 2024.06.02 |
(Node.js) 업로드 이미지 리사이징 (0) | 2024.06.01 |
(Node.js) 서버에서 차트 그려서 이미지로 변환 (0) | 2024.02.25 |