Skip to main content
  1. References/
  2. Architecture Design Basics/
  3. Pattern Taxonomy/
  4. Communication & API Design/

Web-gRPC Proxy

·· 535 words· 3 mins

🟠 P1 — decoupling internal gRPC from external REST via a stateless proxy

Problem #

Modern browsers can’t make gRPC calls directly (gRPC/2 requires HTTP/2 with special framing).

External API consumers often expect REST.

We need a translation layer.

Architecture #

Common implementations: gRPC-Gateway, Envoy proxy, custom reverse proxy.

Browser/External Client
        ↓
   [REST Endpoint]
        ↓
   gRPC Proxy (translates REST β†’ gRPC)
        ↓
   Internal gRPC Services

Key Tradeoffs #

Latency & Protocol Overhead #

AspectgRPC (Internal)REST + ProxyREST Direct
SerialisationBinary protobuf (~fast)Binary β†’ JSON β†’ BinaryJSON only (~slower)
Frame overheadMinimal (HTTP/2 framing)HTTP/1.1 or HTTP/2HTTP/1.1 (~higher)
Typical impactBaseline+5-10ms per hop+20-30% larger payloads

Instinct:

  • If your external API traffic is <5% of total, the proxy overhead is noise.
  • If >30%, reconsider the boundary (maybe expose gRPC directly, or move work internal).

Complexity & Operational Burden #

  • Direct gRPC to external: Clients need gRPC libs + protobuf knowledge. Harder on-boarding.
  • REST proxy layer: Clients use standard HTTP; you own translation complexity.
    • Tradeoff: Add a service, gain simplicity for consumers.
    • Failure mode: Proxy becomes a bottleneck or single point of failure.

Instinct:

  • Run the proxy stateless & replicated. Make it thin β€” let it delegate routing/auth, not business logic.

Bi-directional Streaming & Real-time #

  • gRPC: HTTP/2 multiplexing + server push = natural streaming.
  • REST + Proxy: HTTP/1.1 long-polling, or WebSocket sidecar (adds another layer).

Instinct:

  • If you need bidirectional streaming to external clients, gRPC-Web (gRPC over HTTP/1.1) is worth the proxy cost.
  • REST long-polling gets ugly at scale.

API Surface and Consistency #

  • Proxy approach: Design for gRPC internally (performance, streaming), expose REST facade (compatibility).

    • Cost: One more layer to maintain & debug.
    • Benefit: Decouples internal & external APIs.
  • No proxy: Standardise on REST everywhere.

    • Cost: Lose gRPC performance internally, or force clients to use gRPC (friction).

Instinct: At Stripe’s scale, the proxy cost is justified by API surface flexibility.

Security, Debugging #

  • gRPC Proxy: Easier to inspect & rate-limit at one point. But binary protobuf is harder to debug (need tools like grpcurl).
  • REST: Human-readable JSON, easier curl/Postman debugging. But larger attack surface if you expose many endpoints.

Tradeoff: Proxy simplifies enforcement (auth, rate-limiting in one place), but complicates visibility (need gRPC-aware monitoring).

Framing: Use-cases #

ScenarioRecommendationWhy
Internal-only backendgRPC directlyNo translation needed; pure speed & efficiency
Public API, mostly readsRESTClients don’t need streaming; simplicity wins
Mixed (internal gRPC + external REST)gRPC-Gateway proxyCentralise translation, keep internal fast
Real-time external updatesgRPC-Web proxyStreaming to browser/mobile clients
High-throughput batch APIsgRPC directlyProtocol overhead dominates

Instinct #

Here’s how we might articulate our instinct on this:

I’d design the internal service mesh on gRPCβ€”it gives us HTTP/2 efficiency and streaming primitives. For external APIs, I’d run a thin, stateless gRPC-Gateway proxy that translates REST to our internal proto. This decouples the API contract (what partners see) from the implementation (what’s fast internally). The proxy is a deliberate complexity boundary: it costs us ~5-10ms per external request, but it buys us: (1) API evolution freedom, (2) operational simplicity β€” one place for auth, rate-limiting, observability, (3) protocol flexibility β€” we can add gRPC-Web later if we need browser streaming.

DDIA 2e Reference #

  • Chapter 4 (Encoding and Evolution): Serialisation formats, schema evolution, compatibility
  • Chapter 8: Network faults, partial failures informing proxy resilience