#rpc #grpc #grpc-web

tonic-web

grpc-web protocol translation for tonic services

4 releases (breaking)

0.4.0 Jul 29, 2022
0.3.0 Apr 1, 2022
0.2.0 Oct 25, 2021
0.1.0 Jul 8, 2021

#1162 in Network programming

Download history 7209/week @ 2022-06-07 14061/week @ 2022-06-14 42238/week @ 2022-06-21 41547/week @ 2022-06-28 45735/week @ 2022-07-05 45410/week @ 2022-07-12 17386/week @ 2022-07-19 6431/week @ 2022-07-26 6150/week @ 2022-08-02 5884/week @ 2022-08-09 5411/week @ 2022-08-16 7766/week @ 2022-08-23 9316/week @ 2022-08-30 8141/week @ 2022-09-06 7236/week @ 2022-09-13 4242/week @ 2022-09-20

30,815 downloads per month
Used in 6 crates (4 directly)

MIT license

475KB
10K 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

~7–13MB
~231K SLoC