The Problem grpc-gateway Solves
Not every client that needs to talk to a gRPC-based backend can actually speak gRPC — browsers without grpc-web tooling, third-party webhook senders, legacy REST-only integrations, and simple curl-based health checks all expect plain HTTP/1.1 with JSON bodies, not HTTP/2 framed Protobuf. grpc-gateway solves this by generating a reverse-proxy server from your .proto definitions that accepts standard REST/JSON requests, translates them into the equivalent gRPC call against your real backend service, and translates the Protobuf response back into JSON — so you write and maintain one gRPC service and get a REST-compatible facade essentially for free.
Cricket analogy: Like a translator at a post-match press conference converting an English-speaking coach's answers into the local language for reporters who don't follow English, grpc-gateway translates JSON/REST requests into gRPC calls for clients that don't speak Protobuf natively.
Annotating Proto Files for HTTP Mapping
The translation is driven by google.api.http annotations placed directly on each RPC method in the .proto file: option (google.api.http) = { get: "/v1/users/{user_id}" } maps a GetUser RPC to an HTTP GET with a path parameter, while post: "/v1/users" body: "*" maps a CreateUser RPC to an HTTP POST whose entire JSON body is deserialized into the request message. Path templates can capture multiple fields, like /v1/users/{user_id}/orders/{order_id}, and grpc-gateway supports the full standard verb set — get, post, put, delete, patch — letting the generated REST surface follow normal REST resource-naming conventions even though the underlying implementation is a Protobuf RPC.
Cricket analogy: Like a fixture list mapping each specific match to a specific stadium and date, google.api.http annotations map each specific RPC method to a specific HTTP verb and URL path template.
service UserService {
rpc GetUser (GetUserRequest) returns (User) {
option (google.api.http) = {
get: "/v1/users/{user_id}"
};
}
rpc CreateUser (CreateUserRequest) returns (User) {
option (google.api.http) = {
post: "/v1/users"
body: "*"
};
}
}Generating and Running the Gateway
Running protoc (or buf generate) with the protoc-gen-grpc-gateway plugin produces Go code implementing a http.Handler / ServeMux that, for each annotated method, parses the incoming HTTP request, marshals it into the corresponding Protobuf request message, and forwards it via a real gRPC client connection to your backend service — the gateway doesn't reimplement your business logic, it's purely a translation layer. In production this gateway typically runs as its own process (often a sidecar container) listening on the REST port while proxying every call over gRPC to the actual service, which means you get to keep exactly one source of truth for your API logic while serving two protocols.
Cricket analogy: Like a stadium's ball-by-ball radio commentator relaying the on-field action to listeners without playing in the match themselves, the generated gateway relays REST requests to the real gRPC backend without reimplementing any business logic itself.
grpc-gateway doesn't replace your gRPC server — it runs as a separate process (often a sidecar) that forwards every translated REST call over a real gRPC client connection to your actual backend, so your business logic and validation live in exactly one place.
Limitations and When to Use It
grpc-gateway's translation has real limits: server-streaming RPCs get flattened into a chunked, line-delimited JSON response rather than true HTTP/2 streaming, and bidirectional or client-streaming RPCs generally aren't representable over REST/JSON at all, so a chat-style or real-time bidi API can't be exposed through the gateway. There's also a real latency cost — every gateway request pays for JSON parsing, Protobuf marshaling, and an extra network hop to the backend gRPC server — so grpc-gateway is best treated as a compatibility shim for external or legacy consumers who need REST, not as the primary way internal services should talk to each other, where you'd want direct gRPC clients instead.
Cricket analogy: Like trying to broadcast a live over-by-over commentary through a medium that only supports still photos, a bidirectional streaming RPC like a live match-analysis chat can't be represented over REST/JSON through grpc-gateway.
Don't design your RPC methods around REST/JSON conventions just because you plan to expose them through grpc-gateway — define the cleanest gRPC API first, add google.api.http annotations afterward, and accept that a handful of streaming methods simply won't have a REST equivalent.
- grpc-gateway generates a reverse-proxy that translates REST/JSON requests into gRPC calls and back.
- google.api.http annotations on each RPC method define the HTTP verb and path template mapping.
- The generated gateway forwards translated calls via a real gRPC client to the backend, without duplicating business logic.
- The gateway typically runs as its own process (often a sidecar), keeping a single source of truth for logic.
- Server-streaming RPCs become chunked JSON through the gateway; bidirectional/client-streaming isn't representable over REST.
- Using the gateway adds latency from double serialization and an extra network hop.
- Design the gRPC API first, then add HTTP annotations — don't let REST conventions dictate the gRPC contract.
Practice what you learned
1. What problem does grpc-gateway primarily solve?
2. What does the google.api.http annotation on an RPC method define?
3. Does the grpc-gateway process reimplement the backend's business logic?
4. What happens to a server-streaming RPC when exposed through grpc-gateway?
5. Why can't bidirectional streaming RPCs generally be exposed through grpc-gateway?
Was this page helpful?
You May Also Like
gRPC Interceptors
How to use gRPC interceptors to implement cross-cutting logic like logging, authentication, retries, and tracing without touching individual handlers.
Load Balancing in gRPC
Why gRPC's persistent, multiplexed HTTP/2 connections need client-side or proxy-aware load balancing, and how policies like round_robin and least_request work in practice.
gRPC Authentication with TLS
How gRPC uses TLS and mutual TLS to secure transport, and how call credentials layer token-based authorization on top for production services.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics
Web DevelopmentNext.js Study Notes
JavaScript · 30 topics