2 releases

0.8.1-alpha.1 Aug 29, 2022

#39 in #grpc-client

MIT license

52KB
1K 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)
       .add_service(tonic_web::enable(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.

Getting Started

[dependencies]
tonic_web = "0.1"

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. See the Config documentation for details.

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 and server-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

~8–18MB
~232K SLoC