2 min read
gRPC + REST Gateway 병행 전략
내부는 gRPC, 외부는 REST를 유지하면서 운영 복잡도를 통제하는 경계 설계

도입
기존 REST API를 유지하면서 내부 통신을 gRPC로 전환하려면 성능보다 계약 관리가 더 중요하다. 게이트웨이를 도입하면 외부 호환성은 확보되지만, 스키마 버전과 에러 코드 매핑이 느슨하면 디버깅 비용이 급증한다. 이 글은 REST와 gRPC를 병행 운영하는 마이그레이션 단계, 팀 경계, 관측 포인트를 정리한다.

문제 정의
병행 전략이 실패하는 이유는 중간 레이어를 임시 코드로 취급하기 때문이다. 다음 항목을 먼저 고정해야 한다.
- Proto 변경과 OpenAPI 변경이 분리되어 문서와 실제 동작이 어긋난다.
- gRPC status code를 HTTP status로 일관되게 변환하지 않아 클라이언트 장애가 증가한다.
- 게이트웨이 로그에 upstream 메타데이터가 없어 구간별 지연 시간을 추적하기 어렵다.
이전 단계에서는 전환 속도보다 회귀 통제가 우선이다. 계약 테스트와 샘플 트래픽 리플레이를 필수 절차로 넣어야 한다.
핵심 개념
| 관점 | 설계 기준 | 검증 포인트 |
|---|---|---|
| 계약 동기화 | Proto를 단일 소스로 관리 | OpenAPI 자동 생성 여부 |
| 에러 매핑 | gRPC status와 HTTP status 양방향 매핑 표준화 | 클라이언트 재시도 오류율 |
| 성능 | gateway에서 timeout 예산 분할 | p95 latency 증감 |
| 관측 | trace context 전파 | 구간별 지연 원인 추적 |
REST와 gRPC를 병행하는 기간은 아키텍처 리스크가 가장 높은 시기다. 기능 단위 전환 목록과 철수 기준을 함께 문서화해야 한다.
코드 예시 1: gRPC 상태코드 HTTP 매핑
import { status } from "@grpc/grpc-js";
export function grpcToHttp(code: status): number {
switch (code) {
case status.OK:
return 200;
case status.INVALID_ARGUMENT:
return 400;
case status.UNAUTHENTICATED:
return 401;
case status.PERMISSION_DENIED:
return 403;
case status.NOT_FOUND:
return 404;
case status.ALREADY_EXISTS:
return 409;
default:
return 500;
}
}
코드 예시 2: Gateway 핸들러
export async function getUserProfile(req: Request) {
const id = new URL(req.url).searchParams.get("id");
if (!id) return Response.json({ message: "id required" }, { status: 400 });
try {
const result = await grpcClient.GetUser({ id }, { deadline: Date.now() + 300 });
return Response.json(result, { status: 200 });
} catch (error) {
const code = (error as { code?: number }).code;
return Response.json({ message: "upstream error" }, { status: grpcToHttp(code ?? 13) });
}
}
아키텍처 흐름
Mermaid diagram rendering...
Clean Architecture 레이어 구조
병행 기간에는 경계가 흐려지기 쉽기 때문에 Clean Architecture 기준으로 게이트웨이를 어댑터 레이어로 고정하는 것이 안전하다.
| Layer | 책임 | 적용 방식 |
|---|---|---|
| Entities | 요청/응답 도메인 모델 | UserProfile, OrderSummary |
| Use Cases | 프로토콜 독립 비즈니스 로직 | GetUserProfileUseCase |
| Interface Adapters | REST, gRPC 변환 | GatewayController, GrpcPresenter |
| Frameworks | Next.js Route/Env | HTTP 서버, gRPC 클라이언트 |
인프라 구성도
Mermaid diagram rendering...
트레이드오프
- 병행 기간이 길수록 운영 비용은 증가하지만 대규모 클라이언트 호환성을 안정적으로 유지할 수 있다.
- 자동 코드 생성은 생산성이 높지만, 변환 레이어를 이해하지 못하면 장애 분석이 어려워진다.
- 게이트웨이 캐시를 넣으면 지연은 줄지만 캐시 무효화 정책 복잡도가 높아진다.
정리
gRPC 전환은 프로토콜 교체가 아니라 계약 운영 프로젝트다. 게이트웨이를 명확한 어댑터 레이어로 두고, 코드/문서/테스트를 동일 소스로 맞추면 안정적인 단계적 마이그레이션이 가능하다.
이미지 출처
- Cover: source link
- License: Public domain / Author: en:User:Pbroks13
- Note: Wikimedia Commons 무료 라이선스 이미지를 다운로드 후 1600px 기준 JPG로 최적화했습니다.