Nodejs

 

NestJS 배달 프로젝트 Microservice - gRPC User Proto 작업하기

 

1. gRPC란 무엇인가?

  • gRPC (Google Remote Procedure Call) 은 Google에서 만든 고성능 RPC(Remote Procedure Call) 프레임워크입니다.

  • Protocol Buffers (proto3) 를 기반으로 데이터 직렬화를 수행하며, JSON보다 가볍고 빠릅니다.

  • 다중 언어 지원, 양방향 스트리밍, 효율적인 네트워크 활용을 장점으로 합니다.

NestJS에서는 @nestjs/microservices 패키지를 통해 gRPC 기반의 마이크로서비스를 쉽게 구축할 수 있습니다.

 

 

2. User Proto 정의 (proto 파일)

아래는 user.proto 예시입니다. AuthService와 UserService를 정의하고, 사용자 인증과 정보 조회를 처리합니다.

syntax = "proto3";

package user;

service AuthService {
    rpc ParseBearerToken(ParseBearerTokenRequest) returns (ParseBearerTokenResponse);
    rpc RegisterUser(RegisterUserRequest) returns (RegisterUserResponse);
    rpc LoginUser(LoginUserRequest) returns (LoginUserResponse);
}

message ParseBearerTokenRequest {
    string token = 1;
}

message ParseBearerTokenResponse {
    string sub = 1;
}

message RegisterUserRequest {
    string token = 1;
    string name = 2;
    int32 age = 3;
    string profile = 4;
}

message RegisterUserResponse {
    string id = 1;
    string email = 2;
    string name = 3;
    int32 age = 4;
    string profile = 5;
}

message LoginUserRequest {
    string token = 1;
}

message LoginUserResponse {
    string refreshToken = 1;
    string accessToken = 2;
}

service UserService {
    rpc GetUserInfo(GetUserInfoRequest) returns (GetUserInfoResponse);
}

message GetUserInfoRequest {
    string userId = 1;
}

message GetUserInfoResponse {
    string id = 1;
    string email = 2;
    string name = 3;
    int32 age = 4;
    string profile = 5;
}

이 proto 파일은 gRPC 서버와 클라이언트 간의 공통 계약서(contract) 역할을 하며, 서비스 간의 강력한 타입 보장을 제공합니다.

 

 

3. NestJS에서 gRPC User Service 구현

NestJS는 @MessagePattern 데코레이터를 이용해 gRPC 요청을 핸들링할 수 있습니다.

 UserController

import {
  Controller,
  UseInterceptors,
  UsePipes,
  ValidationPipe,
} from '@nestjs/common';
import { UserService } from './user.service';
import { MessagePattern, Payload } from '@nestjs/microservices';
import { RpcInterceptor } from '@app/common/interceptor';
import { GetUserInfoDto } from './dto/get-user-info.dto';

@Controller()
export class UserController {
  constructor(private readonly userService: UserService) {}

  @MessagePattern({ cmd: 'get_user_info' })
  @UsePipes(ValidationPipe)
  @UseInterceptors(RpcInterceptor)
  getUserInfo(@Payload() data: GetUserInfoDto) {
    return this.userService.getUserById(data.userId);
  }
}
  • @MessagePattern({ cmd: 'get_user_info' }): gRPC 요청과 매핑

  • ValidationPipe: DTO 유효성 검사

  • RpcInterceptor: 공통 로직(에러 처리, 로깅 등) 적용

 

 

 AuthController

import {
  Controller,
  UnauthorizedException,
  UseInterceptors,
  UsePipes,
  ValidationPipe,
} from '@nestjs/common';
import { AuthService } from './auth.service';
import { RegisterDto } from './dto/register.dto';
import { MessagePattern, Payload } from '@nestjs/microservices';
import { ParseBearerTokenDto } from './dto/parse-bearer-token.dto';
import { RpcInterceptor } from '@app/common/interceptor';
import { LoginDto } from './dto/login.dto';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @MessagePattern({ cmd: 'parse_bearer_token' })
  @UsePipes(ValidationPipe)
  @UseInterceptors(RpcInterceptor)
  parseBearerToken(@Payload() payload: ParseBearerTokenDto) {
    return this.authService.parseBearerToken(payload.token, false);
  }

  @MessagePattern({ cmd: 'register' })
  registerUser(@Payload() registerDto: RegisterDto) {
    const { token } = registerDto;
    if (token === null) {
      throw new UnauthorizedException('토큰을 입력해주세요!!!');
    }
    return this.authService.register(token, registerDto);
  }

  @MessagePattern({ cmd: 'login' })
  loginUser(@Payload() loginDto: LoginDto) {
    const { token } = loginDto;
    if (token === null) {
      throw new UnauthorizedException('토큰을 입력해주세요!');
    }
    return this.authService.login(token);
  }
}
  • parse_bearer_token: 토큰 검증 및 사용자 식별자 추출

  • register: 신규 사용자 등록 처리

  • login: 사용자 로그인 및 토큰 발급

 

 

4. gRPC User Proto 성능 최적화 전략

NestJS + gRPC에서 성능을 극대화하기 위한 핵심 포인트는 다음과 같습니다.

  1. Proto 기반 타입 정의: 불필요한 데이터 직렬화 비용 감소

  2. ValidationPipe 활용: 잘못된 요청 초기에 차단

  3. RpcInterceptor 적용: 로깅, 성능 모니터링, 공통 에러 처리

  4. 서비스 단위 분리: 인증, 유저, 주문, 결제 등 모듈화 및 독립 배포 가능

  5. Protobuf 직렬화: JSON 대비 더 빠르고 효율적인 데이터 처리

 

 

 

 

about author

PHRASE

Level 60  라이트

Adversity makes men, but prosperity makes monsters. (苦生은 사람을 만들고 安逸은 괴물을 만든다.)

댓글 ( 0)

댓글 남기기

작성