Logo

dev-resources.site

for different kinds of informations.

Browser Client to gRPC Server Routing options: Connect, gRPC-web, gRPC-gateway and more!

Published at
8/9/2024
Categories
networking
grpc
envoy
browser
Author
stevenacoffman
Categories
4 categories in total
networking
open
grpc
open
envoy
open
browser
open
Author
14 person written this
stevenacoffman
open
Browser Client to gRPC Server Routing options: Connect, gRPC-web, gRPC-gateway and more!

Browser Client to gRPC Server Routing options: Connect, gRPC-web, gRPC-gateway and more!

These days, gRPC is commonly used and well-supported enough that many options exist for communicating to a gRPC backend from the browser.

For gRPC apps, I quite like using Connect. Connect is a family of libraries for building browser and gRPC-compatible HTTP APIs: you write a short Protocol Buffer schema and implement your application logic, and Connect generates code to handle marshaling, routing, compression, and content type negotiation. It also generates an idiomatic, type-safe client in any supported language.

Connect lets you choose from gRPC, gRPC-Web, and Connect's own protocol, but each protocol has a different set of production routing options.

Choosing a protocol and how to route it!

In Connect: Choosing a protocol shows connect supports gRPC-web as well, but I thought I'd expand on how routing works from the browser for these different protocol choices. As a refresher, this is from Connect's docs:

Connect has Seamless multi-protocol support

Connect servers and clients support three protocols: gRPC, gRPC-Web, and
Connect's own protocol.

  • Connect fully supports the gRPC protocol, including streaming, trailers, and error details. Any gRPC client, in any language, can call a Connect server, and Connect clients can call any gRPC server. We validate our gRPC compatibility with an extended version of Google's own interoperability tests.
  • Connect also offers direct support for the gRPC-Web protocol used by grpc/grpc-web, without relying on a translating proxy like Envoy.
  • Finally, Connect supports its own protocol: a straightforward HTTP-based protocol that works over HTTP/1.1, HTTP/2, and HTTP/3. It takes the best parts of gRPC and gRPC-Web, including streaming, and packages them into a protocol that's equally at home in browsers, monoliths, and microservices. By default, implementations support both JSON- and binary-encoded Protobuf. You can call our live demo service with cURL:


  curl \
      --header "Content-Type: application/json" \
      --data '{"sentence": "I feel happy."}' \
      https://demo.connectrpc.com/connectrpc.eliza.v1.ElizaService/Say


By default, Connect servers support ingress from all three protocols. Clients
default to using the Connect protocol, but can switch to gRPC or gRPC-Web with
a configuration toggle — no further code changes required. The APIs for
errors, headers, trailers, and streaming are all protocol-agnostic.


Connect protocol HTTP Host and Request Path Routing

We get to use traditional HTTP Routing!

The Connect protocol is a simple, POST-only protocol that works over HTTP/1.1 or HTTP/2 (or HTTP/3!). It takes the best portions of gRPC and gRPC-Web, including streaming, and packages them into a protocol that works equally well in browsers, monoliths, and microservices. The Connect protocol is what we think the gRPC Protocol should be. By default, JSON- and binary-encoded Protobuf is supported. Calling a Connect API is as easy as using curl:




# Try it out! This is a live demo!
curl \
    --header "Content-Type: application/json" \
    --data '{"sentence": "I feel happy."}' \
    https://demo.connectrpc.com/connectrpc.eliza.v1.ElizaService/Say


Enter fullscreen mode Exit fullscreen mode

Connect RPC Web

If you have a load balancer, you can use all the familiar HTTP/1.1 or HTTP/2 (or HTTP/3) routing rules to get to the backend (Host or Host+Path). This is my preferred option, and you can use your favorite load balancer. I like Envoy these days.

And inside your server, HTTP/1.1 or HTTP/2 (or HTTP/3) for the Connect protocol would be based on the URL /connectrpc.eliza.v1.ElizaService.


gRPC Routing

In Kubernetes, the common Gateway API spec has experimental support GRPCRoute. AFAICT Envoy Gateway has the most mature support for Gateway API GRPCRoute of the implementations. At least GKE specifically recommends using Envoy as your gRPC gateway.

The source code for that tutorial is here.

Note: Browsers do not support gRPC protocol natively because they do not support HTTP/2 Trailers, nor does the Browser's Fetch API support client streaming. The fetch API does specify streaming request bodies, but unfortunately, browser vendors have not come to an agreement to support streams from the client—see this WHATWG issue on GitHub. This means you can use streaming from the browser, but only server streaming.


gRPC-Gateway: JSON all the things

The gRPC-Gateway project started out after the original author,Yuki Yugui Sonoda, left Google and wanted to use a tool they had been using internally at Google, but couldn’t find an open-source version. So they wrote one!

At its core the gRPC-Gateway is a translation layer between the HTTP/JSON REStful API paradigm and the gRPC/Protobuf API paradigm.

Johan Brandhorst-Satzkorn wrote an excellent article on the ins and outs of gRPC-Gateway.

gRPC-Gateway JSON API

Vanguard: JSON all the things, but also Connect

Vanguard is a nearly seamless replacement for gRPC-Gateway. It replaces the JSON/REST to gRPC translation, but given that it also can translate JSON/REST to Connect, it opens up a few more options.


gRPC-web Routing options

There are two different options, and both of them involve using a proxy like Envoy.

gRPC-web Envoy proxy

grpc-web option 1: grpc-web

In grpc-web, traditional HTTP URL routing works. For instance:



curl 'http://localhost:8080/grpc.gateway.testing.EchoService/Echo' 
-H 'Pragma: no-cache' 
-H 'X-User-Agent: grpc-web-javascript/0.1' 
-H 'Origin: http://localhost:8081' 
-H 'Content-Type: application/grpc-web+proto' 
-H 'Accept: */*' 
-H 'X-Grpc-Web: 1' 
-H 'Connection: keep-alive' --data-binary $'\x00\x00\x00\x00\x05\n\x03abc' --compressed


Enter fullscreen mode Exit fullscreen mode

The URL /grpc.gateway.testing.EchoService would be routed to the service.

grpc-web option 2: gRPC bridging

Envoy also supports gRPC bridging where gRPC-web is translated to gRPC.

See https://github.com/connectrpc/envoy-demo/issues/2

Envoy notes

From Envoy HTTP/3 overview:

While HTTP/3 downstream support is deemed ready for production use, improvements are ongoing, tracked in the area-quic tag.

HTTP/3 upstream support is alpha - key features are implemented but have not been tested at scale.

https://github.com/envoyproxy/gateway/issues/422

From Gophers Slack regarding gRPC routing in GKE:

No particular opinions, it's fine. Google gave up on actually fixing their ingress controller and came up with the Gateway spec instead, It's not super widely supported in the rest of the k8s ecosystem yet. That said, it works very well on GKE for a lot of things.

For anything http1.1 it should work out of the box as an L7 LB.

For http2 to work properly it's likely that between the LB and app it needs to be configured to do TLS, because GCP LBs (regardless if configured with ingress or gateway) does not support h2c (http2 over cleartext) afaik. GKE only implements the HTTPRoute part of the Gateway spec also, so can't do anything protocol-aware for grpc or have tcp vs udp routes either.

Envoy Terminology

grpc Article's
30 articles in total
Favicon
How to Handle Excessive Warning Messages When Running `pecl install grpc`
Favicon
Protocol Buffers as a Serialization Format
Favicon
gRPC, Haskell, Nix, love, hate
Favicon
🚀Build, Implement, and Test gRPC Services with .NET9
Favicon
Using OpenTelemetry with gRPC in Node.js and Express Hybrid Applications
Favicon
Exploring gRPC: The High-Performance Communication in Distributed Systems
Favicon
Wednesday Links - Edition 2024-11-06
Favicon
Part 3: Compiling the Protos and Setting up the gRPC server
Favicon
Mocking gRPC Clients in C#: Fake It Till You Make It
Favicon
How gRPC Works
Favicon
Part 2: Defining the Authentication gRPC Interface
Favicon
How Does gRPC Actually Work?
Favicon
gRPC Streaming: Best Practices and Performance Insights
Favicon
Why is gRPC so much faster than a JSON-based REST API?
Favicon
Strongly typed web APIs with gRPC
Favicon
Use RBAC to protect your gRPC service right on proto definition
Favicon
gRPC and Go: Building High-Performance Web Services
Favicon
Connecting NestJS and ASP.NET Core with gRPC: A Step-by-Step Guide
Favicon
gRPC: what is it? An introduction...
Favicon
gRPC: onde vive? o que come?
Favicon
Understanding the Importance of gRPC and Its Applications in Modern Software Development
Favicon
Mastering Go gRPC Services with Docker: A One-Stop Guide
Favicon
Hybrid NestJs Microservice Responding to Both HTTP and gRPC Requests
Favicon
Part 1: How to build Auth API in Rust using gRPC
Favicon
gRPC between Web and Server.
Favicon
FauxRPC
Favicon
Why should we use Protobuf in Web API as data transfer protocol.
Favicon
Browser Client to gRPC Server Routing options: Connect, gRPC-web, gRPC-gateway and more!
Favicon
gRPC vs REST: A Comprehensive Comparison
Favicon
gRPC - Unimplemented Error 12

Featured ones: