🌐
웹개발
gRPC-Web
브라우저에서 gRPC를 사용하기 위한 프로토콜
브라우저에서 gRPC를 사용하기 위한 프로토콜
gRPC-Web은 웹 브라우저에서 gRPC 서비스를 호출할 수 있게 해주는 프로토콜입니다. 브라우저의 HTTP/2 제약으로 인해 일반 gRPC를 직접 사용할 수 없어 개발되었습니다.
브라우저에서 gRPC-Web 클라이언트가 요청을 보내면, 프록시(Envoy 등)가 이를 표준 gRPC로 변환해 백엔드 서비스와 통신합니다. 이를 통해 프론트엔드도 gRPC의 이점을 활용할 수 있습니다.
다만 양방향 스트리밍은 지원되지 않으며, 프록시 서버가 필수라는 제약이 있습니다.
proto 파일에서 클라이언트 생성
# protobuf 및 grpc-web 플러그인 설치 후
protoc -I=. user.proto \
--js_out=import_style=commonjs:./generated \
--grpc-web_out=import_style=typescript,mode=grpcwebtext:./generated
TypeScript 클라이언트 사용
import { UserServiceClient } from './generated/UserServiceClientPb';
import { GetUserRequest, User } from './generated/user_pb';
// 클라이언트 생성 (Envoy 프록시 주소)
const client = new UserServiceClient('http://localhost:8080');
// Unary 호출
const request = new GetUserRequest();
request.setId(1);
client.getUser(request, {}, (err, response: User) => {
if (err) {
console.error(err);
return;
}
console.log(response.getName()); // "홍길동"
console.log(response.getEmail());
});
// Promise 래퍼 사용
async function fetchUser(id: number): Promise<User> {
const request = new GetUserRequest();
request.setId(id);
return new Promise((resolve, reject) => {
client.getUser(request, {}, (err, response) => {
err ? reject(err) : resolve(response);
});
});
}
Envoy 프록시 설정 (간략)
# envoy.yaml 핵심 설정
http_filters:
- name: envoy.filters.http.grpc_web # gRPC-Web 변환
- name: envoy.filters.http.cors # CORS 처리
- name: envoy.filters.http.router
clusters:
- name: grpc_service
http2_protocol_options: {} # HTTP/2로 백엔드 연결
load_assignment:
endpoints:
- endpoint:
address:
socket_address: { address: backend, port_value: 50051 }
프론트엔드 개발자
"백엔드가 gRPC인데 우리도 gRPC-Web 써야 하나요? REST Gateway가 더 간단한 것 같은데."
백엔드 개발자
"타입 안정성이 필요하면 gRPC-Web이 좋아. proto 파일 하나로 프론트/백 타입이 일치하니까 API 문서 없이도 개발 가능하거든."
데브옵스
"걱정 마, 우리 인프라에 이미 Envoy 있어. gRPC-Web 필터만 추가하면 돼."
양방향 스트리밍 미지원
브라우저 제약으로 클라이언트 스트리밍과 양방향 스트리밍은 지원되지 않습니다. 서버 스트리밍만 가능합니다.
프록시 필수
Envoy, nginx 등의 프록시가 반드시 필요합니다. 인프라 구성이 복잡해질 수 있습니다.
디버깅 어려움
바이너리 프로토콜이라 브라우저 개발자 도구에서 요청/응답을 직접 읽기 어렵습니다.