gRPC-Web Demo
Unary RPCA SayHello unary RPC sent from the browser over HTTP/1.1 via Gcore CDN β no Envoy required. The browser encodes the request as a binary Protobuf frame, nginx proxies it to a Node.js gRPC-Web server, which forwards it to a native gRPC backend over HTTP/2.
Architecture:
Browser (fetch + gRPC-Web framing) β Gcore CDN (TLS termination, HTTP/2) β nginx /grpc/ proxy_pass (HTTP/1.1) β Node.js gRPC-Web proxy :9002 (HTTP/1.1 β gRPC) β Node.js gRPC server :50051 (HTTP/2)
Tech stack:
Service definition (echo.proto)
The contract between client and server, language-agnostic:
syntax = "proto3";
service Echo {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest { string message = 1; }
message HelloReply { string message = 1; }
Live call
Message to send:
Ready.
Request frame
POST /grpc/Echo/SayHello β Content-Type: application/grpc-web+proto
Protobuf payload:
gRPC-Web frame (flags + 4-byte length + payload):
Response frame
Raw bytes returned by the server:
Decoded reply:
gRPC trailers:
Why gRPC-Web instead of native gRPC?
Browsers cannot use native gRPC because they don't expose low-level HTTP/2 framing control. gRPC-Web is a thin adaptation that works over regular HTTP/1.1 fetch() calls, using a 5-byte binary envelope per message. A server-side proxy (here: Node.js, in production: Envoy) translates between the two protocols.
Native gRPC
- HTTP/2 only
- Binary Protobuf frames
- Bidirectional streaming
- Not supported in browsers
- Test with
grpcurl
gRPC-Web
- HTTP/1.1 or HTTP/2
- Same binary Protobuf payload
- Unary + server streaming
- Works in all browsers via fetch()
- Requires a proxy on the server side