16 releases (8 breaking)
0.12.3 | Sep 26, 2024 |
---|---|
0.12.1 | Jul 17, 2024 |
0.11.0 | Feb 8, 2024 |
0.10.2 | Sep 28, 2023 |
0.1.0 | Jul 8, 2021 |
#1830 in Network programming
241,329 downloads per month
Used in 41 crates
(27 directly)
1MB
11K
SLoC
tonic-web
Enables tonic servers to handle requests from grpc-web
clients directly,
without the need of an external proxy.
Getting Started
[dependencies]
tonic-web = "<tonic-web-version>"
Enabling tonic services
The easiest way to get started, is to call the function with your tonic service and allow the tonic server to accept HTTP/1.1 requests:
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse().unwrap();
let greeter = GreeterServer::new(MyGreeter::default());
Server::builder()
.accept_http1(true)
.layer(GrpcWebLayer::new())
.add_service(greeter)
.serve(addr)
.await?;
Ok(())
}
Examples
See the examples folder for a server and client example.
lib.rs
:
grpc-web protocol translation for tonic
services.
tonic_web
enables tonic servers to handle requests from grpc-web clients directly,
without the need of an external proxy. It achieves this by wrapping individual tonic services
with a tower service that performs the translation between protocols and handles cors
requests.
Enabling tonic services
The easiest way to get started, is to call the enable
function with your tonic service
and allow the tonic server to accept HTTP/1.1 requests:
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse().unwrap();
let greeter = GreeterServer::new(MyGreeter::default());
Server::builder()
.accept_http1(true)
.add_service(tonic_web::enable(greeter))
.serve(addr)
.await?;
Ok(())
}
This will apply a default configuration that works well with grpc-web clients out of the box.
You can customize the CORS configuration composing the GrpcWebLayer
with the cors layer of your choice.
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse().unwrap();
let greeter = GreeterServer::new(MyGreeter::default());
Server::builder()
.accept_http1(true)
// This will apply the gRPC-Web translation layer
.layer(GrpcWebLayer::new())
.add_service(greeter)
.serve(addr)
.await?;
Ok(())
}
Alternatively, if you have a tls enabled server, you could skip setting accept_http1
to true
.
This works because the browser will handle ALPN
.
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let cert = tokio::fs::read("server.pem").await?;
let key = tokio::fs::read("server.key").await?;
let identity = Identity::from_pem(cert, key);
let addr = "[::1]:50051".parse().unwrap();
let greeter = GreeterServer::new(MyGreeter::default());
// No need to enable HTTP/1
Server::builder()
.tls_config(ServerTlsConfig::new().identity(identity))?
.add_service(tonic_web::enable(greeter))
.serve(addr)
.await?;
Ok(())
}
Limitations
tonic_web
is designed to work with grpc-web-compliant clients only. It is not expected to handle arbitrary HTTP/x.x requests or bespoke protocols.- Similarly, the cors support implemented by this crate will only handle grpc-web and grpc-web preflight requests.
- Currently, grpc-web clients can only perform
unary
andserver-streaming
calls. These are the only requests this crate is designed to handle. Support for client and bi-directional streaming will be officially supported when clients do. - There is no support for web socket transports.
Dependencies
~5–11MB
~116K SLoC