grpc-ecosystem/grpc-gateway
gRPC to JSON proxy generator following the gRPC HTTP spec
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓5 active contributors
- ✓BSD-3-Clause licensed
Show 3 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Single-maintainer risk — top contributor 84% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/grpc-ecosystem/grpc-gateway)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/grpc-ecosystem/grpc-gateway on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: grpc-ecosystem/grpc-gateway
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/grpc-ecosystem/grpc-gateway shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit today
- 5 active contributors
- BSD-3-Clause licensed
- CI configured
- Tests present
- ⚠ Single-maintainer risk — top contributor 84% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live grpc-ecosystem/grpc-gateway
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/grpc-ecosystem/grpc-gateway.
What it runs against: a local clone of grpc-ecosystem/grpc-gateway — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in grpc-ecosystem/grpc-gateway | Confirms the artifact applies here, not a fork |
| 2 | License is still BSD-3-Clause | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of grpc-ecosystem/grpc-gateway. If you don't
# have one yet, run these first:
#
# git clone https://github.com/grpc-ecosystem/grpc-gateway.git
# cd grpc-gateway
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of grpc-ecosystem/grpc-gateway and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "grpc-ecosystem/grpc-gateway(\\.git)?\\b" \\
&& ok "origin remote is grpc-ecosystem/grpc-gateway" \\
|| miss "origin remote is not grpc-ecosystem/grpc-gateway (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(BSD-3-Clause)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"BSD-3-Clause\"" package.json 2>/dev/null) \\
&& ok "license is BSD-3-Clause" \\
|| miss "license drift — was BSD-3-Clause at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "README.md" \\
&& ok "README.md" \\
|| miss "missing critical file: README.md"
test -f "buf.yaml" \\
&& ok "buf.yaml" \\
|| miss "missing critical file: buf.yaml"
test -f "MODULE.bazel" \\
&& ok "MODULE.bazel" \\
|| miss "missing critical file: MODULE.bazel"
test -f "Makefile" \\
&& ok "Makefile" \\
|| miss "missing critical file: Makefile"
test -f "docs/docs/overview/index.md" \\
&& ok "docs/docs/overview/index.md" \\
|| miss "missing critical file: docs/docs/overview/index.md"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/grpc-ecosystem/grpc-gateway"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
gRPC-Gateway is a protoc plugin that generates a reverse-proxy server translating RESTful HTTP/JSON requests into gRPC calls based on google.api.http annotations in .proto files. It allows you to expose a single gRPC service as both native gRPC and traditional REST JSON APIs simultaneously, following the gRPC HTTP spec. Core Go plugin in main repo generates proxy servers; Bazel is primary build system (BUILD.bazel at root, .bazelrc, .bazelversion pinning) with Makefile fallback. Buf (buf.yaml, buf.lock) manages protobuf dependencies and generation. Monorepo structure: main plugin logic, docs/ subdirectory with Jekyll site, examples, and GitHub Actions workflows in .github/workflows/. bin/ contains compiled artifacts.
👥Who it's for
Backend engineers building microservices who need to support both gRPC clients (for performance and modern tooling) and REST/JSON clients (for legacy systems, browser APIs, and broader ecosystem compatibility). DevOps teams integrating gRPC services into HTTP-first infrastructure.
🌱Maturity & risk
Production-ready and actively maintained. The project has significant GitHub stars, clear v2 migration documentation (docs/docs/development/grpc-gateway_v2_migration_guide.md), comprehensive CI/CD via GitHub Actions (ci.yml, release.yml), strong Bazel/Buf build system integration, and testimonials from organizations serving millions of requests daily (ADOPTERS.md mentions Ad Hoc). Recent activity visible in .bazelci and workflow definitions.
Low risk for core functionality, but Starlark build config (148KB) adds Bazel complexity. Dual build system (Bazel + Makefile) may confuse contributors. Module.bazel/MODULE.bazel.lock suggests heavy dependency management. The devcontainer.json indicates onboarding friction. No single-maintainer risk visible, but Protobuf ecosystem changes (buf.yaml dependencies) could introduce breaking changes.
Active areas of work
Active CI/CD maintenance (ci.yml, dependabot-auto-merge.yml, renovate.yml suggest automated dependency updates). Release pipeline established (.goreleaser.yml). Documentation-focused work (docs/_layouts, Jekyll site structure). Bazel/build system refinement (.bazelci/presubmit.yml, .bazelversion pinning). Slack community active (badge in README).
🚀Get running
git clone https://github.com/grpc-ecosystem/grpc-gateway.git
cd grpc-gateway
make build
(or use bazel build //... if Bazel is preferred; see Makefile for exact targets)
Daily commands:
This is a code generator, not a service. To use it: protoc --go-grpc_out=. --grpc-gateway_out=. your_service.proto. To develop the generator itself: make test or bazel test //.... See Makefile and .github/workflows/ci.yml for CI test targets.
🗺️Map of the codebase
README.md— Entry point explaining gRPC-Gateway's core purpose as a gRPC-to-JSON proxy generator and its role in the gRPC ecosystem.buf.yaml— Protobuf module configuration that defines how the gateway processes and generates code from proto definitions.MODULE.bazel— Bazel module manifest declaring dependencies and build configuration for the entire project.Makefile— Build automation and development workflow entry point for common tasks like generation, testing, and compilation.docs/docs/overview/index.md— High-level architecture documentation explaining how gRPC-Gateway translates gRPC services to HTTP/JSON APIs..github/workflows/ci.yml— CI/CD pipeline defining how code is tested, built, and validated on every commit.examples/internal/browser/package.json— Example project demonstrating real-world browser-based client integration with gRPC-Gateway services.
🧩Components & responsibilities
- Code Generator (buf/protoc plugins) (buf, protoc, proto-gen-go, protoc-gen-grpc-gateway) — Parses .proto files with google.api.http annotations and outputs Go gateway handler code
- Failure mode: Malformed proto or missing annotations cause generation errors; invalid routing annotations crash at startup
- HTTP Server/Router (net/http, gorilla/mux or runtime-bound router) — Listens on HTTP port, routes requests to generated handlers based on URL paths
- Failure mode: Port binding failure or route conflicts prevent server startup
- JSON↔Proto Marshaler (protojson, custom marshaler implementations) — Serializes/deserializes HTTP request/response bodies between JSON and protobuf wire format
- Failure mode: Unmarshaling errors (invalid JSON, type mismatches) return HTTP 400; oversized payloads may cause OOM
- gRPC Dialer & Caller (grpc.ClientConn, unary/stream RPC calls) — Establishes connections to backend gRPC services and invokes methods with marshaled arguments
- Failure mode: Connection failures, service unavailability, or gRPC error codes propagate as HTTP errors
- Middleware/Interceptor Chain (grpc.UnaryInterceptor, HTTP middleware patterns) — Pre/post-processing hooks for logging, tracing, authentication, request validation
- Failure mode: Panics or blocking operations in middleware hang requests; auth failures may silently drop connections
🔀Data flow
Browser/REST Client→HTTP Server (gRPC-Gateway)— Client sends HTTP request with JSON body to gateway endpointHTTP Server→Route Handler (generated)— Mux routes request to appropriate handler based on URL path and
🛠️How to make changes
Add a new gRPC-to-HTTP service mapping
- Define your gRPC service in a .proto file with google.api.http annotations (
docs/docs/mapping/grpc_api_configuration.md) - Update buf.yaml to include your proto package in the module (
buf.yaml) - Run code generation via Makefile or buf cli to create gateway stubs (
Makefile) - Implement your gRPC service handler and register it with the gateway router (
docs/docs/tutorials/creating_main.go.md)
Customize OpenAPI/Swagger output for documentation
- Add proto options and annotations to your service definitions (
docs/docs/mapping/customizing_openapi_output.md) - Configure code generation rules in buf.gen.yaml to include OpenAPI plugin (
buf.gen.yaml) - Reference the generated OpenAPI spec in your API documentation or Swagger UI (
docs/docs/mapping/openapi_v3.md)
Integrate a custom request/response marshaler
- Review marshaler patterns and httpbody message handling (
docs/docs/mapping/custom_marshalers.md) - Implement custom marshaler in your gateway initialization code (
docs/docs/tutorials/creating_main.go.md) - Test marshaler with example requests from the browser test suite (
examples/internal/browser/package.json)
Set up tracing and observability
- Review tracing integration patterns and middleware setup (
docs/docs/operations/tracing.md) - Configure logging in your gateway main.go following examples (
docs/docs/operations/logging.md) - Verify CI/CD collects observability metrics via workflows (
.github/workflows/ci.yml)
🔧Why these technologies
- Protocol Buffers (protobuf) — Industry-standard for gRPC service definition and serialization; enables strict typing and backward compatibility
- Go — gRPC-Gateway is written in Go for performance, concurrent request handling, and native gRPC library support
- Bazel — Hermetic, reproducible builds across multiple languages and platforms; integrates proto compilation and Go builds
- google.api.http annotations — Declarative way to bind gRPC methods to HTTP routes following the gRPC HTTP spec
⚖️Trade-offs already made
-
Code generation vs. runtime reflection
- Why: gRPC-Gateway generates proxy code at build time rather than using pure reflection
- Consequence: Faster runtime performance and type safety, but requires regeneration when proto changes
-
JSON as default HTTP serialization
- Why: Matches REST API conventions and browser/JavaScript expectations
- Consequence: Loses some protobuf efficiency gains; requires marshaling overhead per request
-
Annotation-based routing over configuration files
- Why: Route definitions live alongside proto service definitions, reducing drift
- Consequence: Tighter coupling between proto and HTTP API design; limited late-stage routing customization
🚫Non-goals (don't propose these)
- Does not handle gRPC authentication/authorization—leaves that to the underlying gRPC service
- Does not provide real-time bidirectional streaming over HTTP 1.1—unary and server-streaming only
- Not a message queue or event bus—purely synchronous request-response proxy
- Does not generate client SDKs for languages beyond OpenAPI spec compatibility
🪤Traps & gotchas
- Bazel vs Makefile: repo uses both; unclear which is canonical. Make sure tooling matches your environment. 2) buf.gen.yaml and buf.yaml orchestrate .proto generation separately from BUILD.bazel—changes to one may not sync with the other. 3) .bazelversion pins a specific Bazel version; mismatches cause hard-to-debug build failures. 4) Devcontainer present (.devcontainer/devcontainer.json) but not required; some developers expect Docker setup. 5) MODULE.bazel.lock is checked in; don't assume go.mod is source of truth for dependencies. 6) Google API dependencies (google.api.http.proto) are external; buf.lock pins them.
🏗️Architecture
💡Concepts to learn
- Reverse-proxy transcoding — gRPC-Gateway's core function is HTTP request->gRPC call transcoding; understanding how it marshals JSON to protobuf and back is essential
- google.api.http annotations — The .proto file annotations that configure how REST routes map to gRPC methods; you must write these to use gRPC-Gateway
- Protoc plugin architecture — gRPC-Gateway is a protoc CodeGenerator plugin; understanding plugin protocol (stdin/stdout of FileDescriptorProto) explains code generation
- gRPC HTTP/2 semantic mapping to REST — The project implements the gRPC HTTP spec which defines how gRPC calls (streaming, metadata, errors) map to HTTP/1.1 or HTTP/2
- Bazel monorepo build system — Project uses Bazel as primary build; understanding BUILD.bazel files, .bazelrc config, and MODULE.bazel dependencies is necessary to contribute
- Buf package management and code generation — buf.yaml and buf.lock manage proto dependencies and generation config; alternative to manual protoc invocation and easier dependency management
- Context propagation in gRPC — The gateway must forward gRPC metadata (auth, tracing) from HTTP headers to gRPC context; understanding context.Context propagation is key to debugging issues
🔗Related repos
googleapis/googleapis— Provides google.api.http proto annotations and reference implementations that gRPC-Gateway depends on and must stay compatible withgrpc/grpc— Core gRPC runtime and protoc plugin ecosystem; gRPC-Gateway is a peer plugin that extends gRPC's code generationgrpc-ecosystem/grpc-json-transcoder— Alternative C++ approach to HTTP<->gRPC transcoding; shows different architecture for same problem in different languagebufbuild/buf— Build system and package manager for protobuf that gRPC-Gateway integrates with (buf.yaml, buf.lock, buf.gen.yaml); users need both toolsprotocolbuffers/protobuf— Core protoc compiler that gRPC-Gateway extends as a plugin; breaking changes in protoc versions can affect gateway generation
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add Cygwin installation tests to CI pipeline
The repo has a Cygwin-specific installation guide at docs/docs/development/installation_for_cygwin.md, but there's no CI validation for Cygwin builds in .github/workflows/ci.yml. This means Cygwin users may encounter undetected regressions. Adding a Windows Cygwin test job would prevent breakage for this platform-specific user segment.
- [ ] Review .github/workflows/ci.yml to understand current test matrix
- [ ] Examine docs/docs/development/installation_for_cygwin.md to identify setup steps required
- [ ] Add a new CI job using windows-latest runner with Cygwin toolchain installation
- [ ] Run the same test suite against the Cygwin build to ensure compatibility
- [ ] Document the Cygwin CI job in CONTRIBUTING.md
Add integration tests for browser-based OpenAPI/Swagger client workflows
The repo includes swagger-client and webpack in devDependencies and the README mentions Swagger UI examples in docs/assets/images, but there are no browser integration tests validating that generated OpenAPI specs work with Swagger UI or swagger-client. The postinstall script for Playwright is configured but underutilized. Adding E2E tests would catch spec generation regressions early.
- [ ] Review docs/docs/mapping/openapi_v3.md and customizing_openapi_output.md to understand spec generation
- [ ] Create a test in test/ directory that generates OpenAPI specs from example protos
- [ ] Use webpack to bundle swagger-client with the generated spec
- [ ] Use Playwright to load the bundled client in a browser and validate API calls succeed
- [ ] Add this test to .github/workflows/ci.yml under a new 'Browser Integration' job
Add health check handler examples and tests for operations guide
The docs/docs/operations/health_check.md exists but lacks concrete implementation examples. The grpc-gateway supports gRPC health checks, but there's no example code or unit tests showing how to properly integrate health check services with the generated gateway. This is critical for production deployments.
- [ ] Review docs/docs/operations/health_check.md to understand current documentation gaps
- [ ] Create example proto definitions in examples/ directory for health.proto with health check service
- [ ] Generate gateway code using those protos and create a runnable example server
- [ ] Add unit tests in internal/ or similar directory validating health check requests return correct status codes
- [ ] Update health_check.md with links to the new example and test coverage
- [ ] Verify example works in .github/workflows/ci.yml
🌿Good first issues
- Add integration test coverage for the HTTP->gRPC routing with complex nested message types—the .bazelci/presubmit.yml suggests this exists but examining examples/ and test/ subdirectories would reveal gaps in documentation of edge cases.
- Improve error messages in the generated proxy server—currently generic HTTP 500 responses don't map gRPC error codes to REST semantics; a new contributor could add a mapping table in the generator and test it against googleapis/googleapis examples.
- Document common Buf + Bazel + protoc orchestration workflows in docs/docs/contributing/getting_started.md—the devcontainer.json and .github setup suggest this is painful; a guide with shell examples would help.
⭐Top contributors
Click to expand
Top contributors
- @renovate[bot] — 84 commits
- @dependabot[bot] — 8 commits
- @johanbrandhorst — 6 commits
- @alliasgher — 1 commits
- @Copilot — 1 commits
📝Recent commits
Click to expand
Recent commits
02b5a86— chore(deps): update dependency gazelle to v0.51.0 (#6768) (renovate[bot])8268567— fix(deps): update module golang.org/x/text to v0.37.0 (#6769) (renovate[bot])32edfed— chore(deps): update google/oss-fuzz digest to c4ba43b (#6766) (renovate[bot])4b75707— chore(deps): update googleapis digest to 33487db (#6767) (renovate[bot])effe79f— build(deps-dev): bump fast-uri in /examples/internal/browser (#6765) (dependabot[bot])53c3ada— chore(deps): update dependency bazel_gazelle to v0.51.0 (#6764) (renovate[bot])767c12d— chore(deps): update google/oss-fuzz digest to c93143e (#6763) (renovate[bot])c628c26— chore(deps): update googleapis digest to b5a00fe (#6762) (renovate[bot])747896e— chore(deps): update google/oss-fuzz digest to b4ad4f8 (#6761) (renovate[bot])28e76b1— chore(deps): update google/oss-fuzz digest to 72d20a2 (#6760) (renovate[bot])
🔒Security observations
- High · Outdated Playwright Dependency —
package.json - devDependencies. The package.json specifies playwright ^1.49.1. While this version is relatively recent, playwright should be kept up-to-date as it may contain security patches for browser automation vulnerabilities. Regular dependency updates are critical for test automation tools that interact with browsers. Fix: Update playwright to the latest stable version. Run 'npm update playwright' and test thoroughly. Consider using automated dependency management tools like Dependabot (already configured in .github/dependabot.yml). - High · Webpack Security Configuration Gap —
package.json - devDependencies / Missing webpack.config.js. Webpack v5.97.1 is specified but there is no visible webpack security configuration file (webpack.config.js). Without explicit security settings, webpack may default to configurations that could expose source maps or sensitive build artifacts in production builds. Fix: Create a webpack.config.js with production-safe settings: set mode to 'production', disable source maps in production, implement proper code splitting, and validate the build output does not expose sensitive information. - Medium · Postinstall Script Risk —
package.json - scripts.postinstall. The package.json contains a postinstall script that automatically downloads and installs Chromium via Playwright. Automatic binary downloads during npm install can pose supply chain risks if the package registry or Playwright's CDN are compromised. This also increases installation time and disk space requirements. Fix: Consider using PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 environment variable for CI/CD pipelines. Document the postinstall behavior clearly. Verify integrity of downloaded binaries using checksums when possible. Consider caching the browser in your build system instead. - Medium · Missing npm Audit and Lockfile Integrity —
package.json - all dependencies use caret ranges (^). While package-lock.json or yarn.lock is not visible in the provided structure, the absence of explicit security scanning instructions (e.g., npm audit in CI/CD) could allow vulnerable dependencies to slip through. The package.json does not specify exact versions (uses ^ caret ranges), allowing minor version updates that may introduce vulnerabilities. Fix: Use 'npm audit' in CI/CD pipelines. Consider using npm ci instead of npm install in production/CI environments. Review and lock critical dependencies to specific versions. Enable GitHub's dependency scanning via .github/dependabot.yml (already present). - Medium · Swagger-Client Dependency —
package.json - devDependencies. swagger-client ^2.1.32 is included in devDependencies. This client library may be exposed if the development dependencies are accidentally bundled into production builds. Swagger/OpenAPI client libraries have had security issues in the past related to XML External Entity (XXE) attacks and JSON parsing. Fix: Ensure swagger-client is truly a devDependency only and never bundled in production. Validate that OpenAPI/Swagger schemas are from trusted sources. Keep the library updated. Consider using a more minimal or type-safe API client if possible. - Low · Missing License Specification —
package.json - license field. The package.json contains 'license': 'SEE LICENSE' which is unconventional. While the repository contains a LICENSE file, this non-standard license field may cause issues with dependency analysis tools and license compliance scanning. Fix: Use a standard SPDX license identifier (e.g., 'Apache-2.0', 'MIT', 'BSD-3-Clause'). If a custom license is used, reference it properly: 'license': 'Apache-2.0' or include the full license text in the field. - Low · No Security Policy Visible —
Repository root. The file structure does not show a SECURITY.md file that documents security reporting procedures. This is a best practice for open-source projects to handle vulnerability disclosures responsibly. Fix: Create a SECURITY.md file following GitHub's recommended format. Include instructions for reporting security vulnerabilities privately (e.g., via security advisory feature). Reference it in README.md. - Low · Missing CODEOWNERS File —
.github. No CODEOWNERS file is visible, which means automated security review and approval workflows may not be properly enforced for critical files. Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.