--- id: wiki-2026-0508-grpc-and-protocol-buffers title: gRPC and Protocol Buffers category: 10_Wiki/Topics status: verified canonical_id: self aliases: [gRPC, Protobuf, protocol-buffers] duplicate_of: none source_trust_level: A confidence_score: 0.95 verification_status: applied tags: [rpc, networking, protobuf, microservices, http2] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: Multi (Go, Rust, TS, Python) framework: gRPC + Protobuf 3 / Edition 2024 --- # gRPC and Protocol Buffers ## 매 한 줄 > **"매 schema-first IDL + HTTP/2 RPC + binary serialization 의 stack."**. Protocol Buffers 는 2008 Google 공개, gRPC 는 2015 OSS — 매 internal Stubby 의 successor. 매 2026 microservice / cross-language API 의 매 default — 매 REST+JSON 보다 5-10× compact, 매 streaming 매 native, 매 contract 강제. ## 매 핵심 ### 매 Protocol Buffers - **Schema**: `.proto` file — 매 message + service 정의. - **Wire format**: tag-length-value, varint encoding — 매 forward/backward compat (unknown field 보존). - **Edition 2024**: `proto2` / `proto3` 의 통합 — 매 explicit feature flag. - **Compiler**: `protoc` + plugin (go, ts-proto, prost, python-betterproto). ### 매 gRPC - **Transport**: HTTP/2 — 매 multiplexing, header compression (HPACK). - **4 RPC types**: unary, server-stream, client-stream, bidi-stream. - **Status codes**: 매 `OK`, `INVALID_ARGUMENT`, `UNAUTHENTICATED`, `DEADLINE_EXCEEDED` (16개 표준). - **Deadline**: 매 client → server propagate. 매 RPC chain 매 cumulative. - **Metadata**: 매 trailer/header — auth token, trace. - **gRPC-Web**: 매 browser support (HTTP/1.1 fallback proxy). - **Connect / gRPC-Gateway**: 매 REST+gRPC dual. ### 매 응용 1. Microservice internal RPC. 2. Mobile ↔ backend (Square, Netflix). 3. Service mesh (Envoy, Istio). 4. Streaming (live ML inference, IoT). ## 💻 패턴 ### .proto schema ```protobuf edition = "2024"; package shop.v1; option go_package = "github.com/example/shop/v1;shopv1"; service Catalog { rpc GetProduct(GetProductRequest) returns (Product); rpc StreamUpdates(StreamUpdatesRequest) returns (stream ProductUpdate); rpc UploadImages(stream Image) returns (UploadAck); rpc Chat(stream ChatMsg) returns (stream ChatMsg); } message GetProductRequest { string id = 1; } message Product { string id = 1; string name = 2; int64 price_cents = 3; repeated string tags = 4; google.protobuf.Timestamp updated_at = 5; } ``` ### Go server (unary + stream) ```go type catalogServer struct{ shopv1.UnimplementedCatalogServer } func (s *catalogServer) GetProduct(ctx context.Context, req *shopv1.GetProductRequest) (*shopv1.Product, error) { if req.Id == "" { return nil, status.Error(codes.InvalidArgument, "id required") } p, err := s.db.Find(ctx, req.Id) if errors.Is(err, sql.ErrNoRows) { return nil, status.Error(codes.NotFound, "product missing") } return p, err } func (s *catalogServer) StreamUpdates(req *shopv1.StreamUpdatesRequest, srv shopv1.Catalog_StreamUpdatesServer) error { for ev := range s.bus.Subscribe(srv.Context()) { if err := srv.Send(ev); err != nil { return err } } return nil } ``` ### TS client (ts-proto + grpc-js) ```typescript import { credentials } from '@grpc/grpc-js'; import { CatalogClient } from './gen/shop/v1/catalog'; const client = new CatalogClient('catalog:50051', credentials.createSsl()); const p = await client.getProduct({ id: 'sku-42' }, { deadline: Date.now() + 1000 }); console.log(p.name); // streaming const stream = client.streamUpdates({}); stream.on('data', (u) => console.log('update', u)); stream.on('error', (e) => console.error(e)); ``` ### Deadline propagation ```go ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond) defer cancel() // 매 outgoing RPC 매 자동 deadline 전달. resp, err := downstream.Sub(ctx, req) ``` ### Interceptor (auth + tracing) ```go func authUnary(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { md, _ := metadata.FromIncomingContext(ctx) tok := md.Get("authorization") if len(tok) == 0 { return nil, status.Error(codes.Unauthenticated, "no token") } user, err := verify(tok[0]) if err != nil { return nil, status.Error(codes.Unauthenticated, "bad token") } return handler(context.WithValue(ctx, userKey{}, user), req) } s := grpc.NewServer(grpc.UnaryInterceptor(authUnary)) ``` ### gRPC-Web (browser) ```typescript import { createPromiseClient } from '@connectrpc/connect'; import { createGrpcWebTransport } from '@connectrpc/connect-web'; import { Catalog } from './gen/shop/v1/catalog_connect'; const transport = createGrpcWebTransport({ baseUrl: 'https://api.example.com' }); const client = createPromiseClient(Catalog, transport); const p = await client.getProduct({ id: 'sku-42' }); ``` ### Buf for build + lint ```yaml # buf.yaml version: v2 modules: - path: proto lint: use: [DEFAULT] breaking: use: [FILE] ``` ```bash buf lint buf breaking --against '.git#branch=main' buf generate ``` ### Backward-compat 규칙 ```protobuf message Product { string id = 1; string name = 2; // 매 deprecated 후에도 number 재사용 X reserved 3; reserved "old_price"; int64 price_cents = 4; } ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | 매 internal microservice | gRPC unary + interceptor | | 매 browser client | Connect / gRPC-Web | | 매 public open API | REST/JSON or gRPC-Gateway dual | | 매 streaming (logs, ML) | server-stream / bidi | | 매 mobile (cellular flaky) | gRPC + retry interceptor + deadline | **기본값**: 매 internal = gRPC, 매 external = Connect (dual REST + gRPC). ## 🔗 Graph - 변형: [[Connect_RPC]] - 응용: [[Service_Mesh]] · [[Microservices]] · [[Envoy]] - Adjacent: [[Buf]] · [[OpenAPI]] ## 🤖 LLM 활용 **언제**: 매 cross-language API, 매 streaming, 매 strict contract. **언제 X**: 매 simple browser CRUD (REST 충분), 매 ad-hoc tooling (JSON 직관적). ## ❌ 안티패턴 - **Field number 재사용**: 매 wire-incompatible — 매 reserved 의 사용. - **매 required 다용**: 매 schema evolution 차단 — proto3 default optional 유지. - **매 deadline 미설정**: 매 server cascade hang. - **매 large message (>4MB)**: 매 default limit hit — 매 stream 으로 분할. - **매 .proto 의 versioning X**: 매 `v1`, `v2` package 분리 mandatory. ## 🧪 검증 / 중복 - Verified (grpc.io docs, protobuf.dev Edition 2024 spec, Buf docs). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — gRPC patterns, Edition 2024, Connect-RPC |