gRPC-Web — Complete Guide
In this tutorial, you will learn about grpc. We cover key concepts, practical examples, and best practices to help you master this topic.
gRPC-Web enables browser applications to call gRPC services. Unlike native gRPC, gRPC-Web works through HTTP/1.1 or HTTP/2 and requires a proxy. This lesson covers setup, client usage, and limitations.
What You'll Learn
- How gRPC-Web differs from native gRPC
- How to set up an Envoy proxy for gRPC-Web
- How to use the gRPC-Web JavaScript client
- How to handle streaming limitations
- Production deployment considerations
Why It Matters
Modern web applications increasingly use gRPC for backend services. gRPC-Web bridges the gap between browser clients and gRPC backends, enabling efficient API communication without REST wrappers.
Real-World Use
A SaaS platform uses gRPC-Web to power its React-based dashboard. When users view analytics, the browser directly calls gRPC services through Envoy, reducing latency by 40% compared to the previous REST-based approach.
Flow Chart
flowchart LR
A[Browser] -->|HTTP/1.1| B[Envoy Proxy]
B -->|HTTP/2| C[gRPC Server]
C --> D{Response}
D -->|Unary| E[JSON/Binary]
D -->|Stream| F[Chunked Response]
E --> B
F --> B
B --> A
Code Examples
Example 1: Envoy Proxy Configuration for gRPC-Web
static_resources:
listeners:
- name: web_listener
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: grpc_web
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: grpc_backend
http_filters:
- name: envoy.filters.http.grpc_web
- name: envoy.filters.http.router
clusters:
- name: grpc_backend
type: STRICT_DNS
lb_policy: ROUND_ROBIN
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
load_assignment:
cluster_name: grpc_backend
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: localhost
port_value: 50051
Expected output: Envoy listens on port 8080, translates gRPC-Web requests to native gRPC, and proxies to the backend on port 50051.
Example 2: gRPC-Web Client in JavaScript
import { HelloRequest, HelloReply } from './helloworld_pb.js';
import { GreeterClient } from './helloworld_grpc_web_pb.js';
const client = new GreeterClient(
'http://localhost:8080');
const request = new HelloRequest();
request.setName('Alice');
client.sayHello(request, {},
(err, response) => {
if (err) {
console.error('Error:', err.message);
return;
}
console.log('Response:',
response.getMessage());
});
// Output: Response: Hello Alice
Expected output: Browser sends gRPC-Web request to Envoy and receives the greeting response.
Example 3: gRPC-Web with TypeScript and Async/Await
import { GreeterClient } from './helloworld_grpc_web_pb';
import { HelloRequest } from './helloworld_pb';
async function greet(name: string): Promise<string> {
const client = new GreeterClient(
'http://localhost:8080',
null, null);
return new Promise((resolve, reject) => {
const request = new HelloRequest();
request.setName(name);
client.sayHello(request, {},
(error: grpcWeb.Error, response: HelloReply) => {
if (error) {
reject(new Error(error.message));
} else {
resolve(response.getMessage());
}
});
});
}
greet('Bob').then(console.log);
// Output: Hello Bob
Expected output: TypeScript client calls gRPC service through Envoy proxy and logs the response.
Common Mistakes
| Mistake | Explanation |
|---|---|
| Expecting full streaming support | gRPC-Web supports limited streaming; server-side streaming works but client-side streaming requires special handling |
| Bypassing the proxy | Browsers cannot call gRPC directly; a proxy like Envoy is always required |
| Using native gRPC libraries in browser | Native gRPC uses HTTP/2 and gRPC-specific features not available in browsers |
| Forgetting CORS configuration | Envoy needs CORS headers configured for browser-based gRPC-Web calls |
| Not handling binary protobuf | gRPC-Web uses binary format; ensure your application can deserialize protobuf messages |
| Ignoring performance implications | Protobuf Serialization in JavaScript can be CPU-intensive for large messages |
Practice Questions
- Why does gRPC-Web require a proxy?
- What streaming types are supported in gRPC-Web?
- How does gRPC-Web handle binary data in browsers?
- What are the performance differences between gRPC and gRPC-Web?
- How do you handle authentication in gRPC-Web?
Challenge
Build a full-stack application with a React frontend using gRPC-Web, an Envoy proxy, and a Go gRPC backend. Implement a real-time chat feature using server-side streaming through gRPC-Web.
FAQ
Mini Project
Build a gRPC-Web application that displays real-time stock prices. Use a Go gRPC server with server-side streaming, an Envoy proxy for gRPC-Web translation, and a React frontend that subscribes to stock price updates and renders them in a dashboard.
What's Next
Build a complete gRPC project applying all concepts
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro