One protobuf contract can serve gRPC and JSON clients
gRPC-Gateway v2 generates Go handlers that translate JSON over HTTP into calls to a gRPC service. Teams annotate RPC methods with google.api.http, use the default mapping for unbound methods, or keep mappings in an external service configuration. The generated proxy preserves one service definition while giving browsers, partner integrations, and command-line clients familiar URLs and JSON bodies. That is a cleaner arrangement than maintaining a second REST implementation whose validation and field names can drift.
The toolchain is larger than the phrase "generate a gateway" suggests. The README installs 4 binaries for Go and gRPC generation, then asks the application to provide a proxy entrypoint and an upstream server. Our 710-file checkout built successfully in 55 seconds, which makes the source easy to work on. Integrating it still changes code generation, module dependencies, deployment topology, and API review. Teams should own those pieces together instead of treating the gateway as a drop-in network appliance.
OpenAPI 3.1 output is alpha in v2.30.0
Release v2.30.0 added a minimal protoc-gen-openapiv3 generator and a separate merge tool. The output targets OpenAPI 3.1.0 and includes JSON Schema constructs such as oneOf for protobuf oneofs. The README also gives the deciding warning: this generator is alpha, emitted shapes may change across minor releases, and the OpenAPI v2 generator remains the production-stable option. Issue 7248 asks for v3 equivalents of security definitions and requirements, which confirms a current gap for documented authentication schemes.
That split matters if generated specifications feed client SDKs, validation, or approval systems. A changed enum or wrapper shape can become a downstream contract change even when the RPC method stays the same. Our checkout held about 209,723 source lines and 5 CI workflow files, evidence of a substantial project rather than a thin converter. For stable Swagger 2.0 output, the project is established. For OpenAPI 3.1, pin the generator and inspect specification diffs before every upgrade.
What happened when we ran it
Our sandbox installed gRPC-Gateway at commit bf7084b in 59 seconds. The run added 162 packages, then completed the build in 55 seconds. The fresh checkout occupied 9.6 MB and contained 710 files. We used Go 1.24 on Debian Bookworm in an unprivileged container with 3 CPUs, 8 GB of RAM, and no secrets. Neither installation nor compilation produced a failure in the supplied run.
The Go test step finished in 15 seconds with 30 passed and 0 failed. Those results cover the repository commands we ran; they do not measure request latency, throughput, generated API compatibility, or a deployed proxy talking to a real backend. Our scan found no Dockerfile and no dedicated tests directory, while 5 CI workflow files were present. The clean run is useful contributor evidence, but each generated service still needs its own route and behavior tests.
HTTP header forwarding needs an explicit policy
Open issue 7281 reports that the default incoming-header matcher can copy arbitrary HTTP headers into gRPC metadata. The reporter argues for opt-in forwarding because an application may trust a metadata field that an outside caller can inject. The issue concerns the default matcher itself, and the documented mitigation is concrete: configure runtime.WithIncomingHeaderMatcher() so the application decides which headers cross the boundary. This deserves attention anywhere metadata carries identity, authorization, tenancy, or internal routing data.
Passing all 30 tests in our 15-second run does not settle an application's trust policy. Generated transport code cannot know whether Authorization, a tenant header, or a custom prefix is safe for a particular service. Treat the HTTP edge as an external input boundary, allow only required metadata, and test rejected headers. The README's example also uses insecure gRPC transport to reach localhost; production code needs credentials suited to its network rather than a copied development option.
The gateway runs beside a gRPC service, not in its place
The README's example listens for HTTP on port 8081 and dials a gRPC server on port 9090. That makes the role plain: gRPC-Gateway translates a request and forwards it, while business logic remains in the gRPC implementation. Streaming RPCs map to newline-delimited JSON streams, HTTP timeouts can become gRPC timeouts, and selected headers can become metadata. Custom marshaling, error handling, and route behavior belong in the gateway entrypoint when defaults do not fit.
Go 1.24 improves tool tracking through the tool directive, but version alignment still matters. The README says the generator and runtime library should use the same version. Remote Buf plugins can avoid local generator installs, though that route is incompatible with external service configuration files. The 59-second installation in our sandbox covered repository dependencies, not a consumer's protobuf imports, Buf registry access, TLS setup, or release pipeline. Budget time for one complete generated service, not just the binary installation.
A 2026-09-12 push and active issues support continued use
GitHub recorded the last push on 2026-09-12, and v2.30.0 was published on 2026-08-05. The repository had 20,002 stars plus 133 open issues and 15 open pull requests when fetched. Recent discussion covered the header matcher, OpenAPI v3 security definitions, and moving examples into a separate Go module. Source changes and issue activity are both current; the combined GitHub count of 148 is issues and pull requests, not a defect count.
The measured 59-second install, 55-second build, and 30 passing tests make gRPC-Gateway a low-risk trial for a Go team already committed to protobuf. Envoy is the better fit when transcoding belongs in an existing proxy fleet. Connect-Go suits controlled clients that can speak its protocol, while ogen fits an OpenAPI-first contract. For the intended job, gRPC-Gateway remains the sensible default, provided the team pins code generators, reviews specification diffs, and owns the HTTP security boundary.

