Backend
gRPC-Gateway로 단일 API 듀얼 프로토콜 지원
하나의 Proto 정의로 gRPC와 HTTP/JSON을 동시에 제공할 때 필요한 구현 포인트를 정리합니다.
gRPC-Gateway로 단일 API 듀얼 프로토콜 지원
왜 쓰는가
동일한 비즈니스 로직을 유지하면서 내부 통신은 gRPC, 외부/브라우저는 HTTP/JSON으로 제공하려는 경우가 많습니다.
gRPC-Gateway는 이 요구를 Proto 중심으로 묶어줍니다.
Proto에 HTTP 매핑 추가
syntax = "proto3";
import "google/api/annotations.proto";
service DocumentService {
rpc GetDocument(GetDocumentRequest) returns (GetDocumentResponse) {
option (google.api.http) = {
get: "/v1/documents/{id}"
};
}
rpc CreateDocument(CreateDocumentRequest) returns (CreateDocumentResponse) {
option (google.api.http) = {
post: "/v1/documents"
body: "*"
};
}
}
코드 생성
# buf.gen.yaml
version: v2
plugins:
- remote: buf.build/grpc/go
out: generated/go
opt: paths=source_relative
- remote: buf.build/grpc-ecosystem/gateway
out: generated/go
opt:
- paths=source_relative
- standalone=true
buf generate
서버 구성 원칙
- gRPC 서버는 단일 진입점으로 유지.
- Gateway는 가능한 인-프로세스 등록(
Register...HandlerServer) 우선. - HTTP와 gRPC 에러 코드를 같은 도메인 코드로 매핑.
최소 부트스트랩 예시
grpcServer := grpc.NewServer()
pb.RegisterDocumentServiceServer(grpcServer, serviceImpl)
gwMux := runtime.NewServeMux()
_ = pb.RegisterDocumentServiceHandlerServer(context.Background(), gwMux, serviceImpl)
http.ListenAndServe(":8080", gwMux)
운영 시 주의사항
- HTTP 레이어가 추가되어 지연이 증가할 수 있음.
- 스트리밍 RPC는 HTTP 변환 시 제약이 큼.
- 인증/인가 정책이 gRPC와 HTTP에서 다르게 흘러가지 않게 공통 미들웨어 정책 필요.
추천 운영 체크리스트
- 경로별 p95/p99를 gRPC/HTTP로 분리 관측.
- OpenAPI 산출물을 CI에서 자동 갱신.
- 클라이언트 계약 테스트로 HTTP 매핑 회귀 방지.
요약
gRPC-Gateway의 핵심 가치는 "중복 구현 제거"입니다. 성공 포인트는 생성 도구가 아니라 Proto 계약, 에러 매핑, 관측 체계를 한 번에 유지하는 데 있습니다.