Tonic: gRPC has come to async/await!
I am pleased to finally announce a crate that I have been working very hard on for the
past few months. tonic
has finally hit the initial 0.1.0-alpha.1
release! Stable
releases will follow in the coming months.
What is Tonic?
Tonic is a gRPC-over-HTTP/2 implementation focused on high performance, interoperability, and flexibility. This library was created to have first class support of async/await and to act as a core building block for production systems written in Rust.
Tonic began its life as tower-grpc
, which was built to satisfy linkerd’s need for a production-ready gRPC implementation. tower-grpc
was based upon futures 0.1
and built ontop of the tower
library, which has production uses in systems such as the linkerd-proxy
, vector
, and the noria
database at MIT. The tower
library has also seen usage in additional libraries such as warp
, tower-web
, and actix-net
.
With async/await’s forthcoming stabilization, we created Tonic to support the new syntax natively. This means clients will support async/await out of the box and server
implementations can be defined via async_trait
s. This provides an unparalleled experience for
writing async services quickly and efficiently. Not only does Tonic provide a fully featured gRPC implementation but it also comes with a fully featured, batteries-included, HTTP/2 client and server built
around hyper
, tokio
and tower
. Both the client and server implementation provide TLS backed by
either openssl
or rustls
. The client provides load balancing, interceptors (middleware), timeouts, rate limiting, concurrency control and more!
Tonic also boasts strong interoperability and correctness. Every commit is checked that it passes
the gRPC interop test cases against the grpc-go
implementation. Hopefully, more
languages can be added in the future.
Features
Tonic’s goal is to provide a good batteries-included experience. It already supports many features, with many more planned! Here is a list of features:
- Implemented in pure Rust (minus
openssl
which is optional) - Interoperability tested via
tonic-interop
- Bi-directional streaming
- Custom metadata
- Trailing metadata
- Codegen via
prost
- Exposes
tracing
diagnostics - Fully featured HTTP/2 client and server based on
hyper
- TLS backed by either
openssl
orrustls
- Load balancing powered by
tower
- Reliability features such as timeouts, rate limiting, concurrency control, and more
- gRPC interceptors
- And much more to come
Overview
helloworld client example:
let mut client = GreeterClient::connect("http://[::1]:50051")?;
let request = Request::new(HelloRequest {
name: "hello".into(),
});
let response = client.say_hello(request).await?;
println!("RESPONSE={:?}", response);
This shows how easy it is to build a simple gRPC client using code generated by the tonic-build
crate. Internally, connect
will create the most basic “channel/client” but it is possible to configure this to support TLS, load balancing, timeouts and more.
helloworld server example:
#[tonic::async_trait]
impl Greeter for MyGreeter {
async fn say_hello(&self, req: Request<HelloRequest>)
-> Result<Response<HelloReply>, Status>
{
println!("Got a request: {:?}", req);
let reply = HelloReply {
message: "Zomg, it works!".into(),
};
Ok(Response::new(reply))
}
}
Servers are simple to implement using dtolnay
’s amazing async_trait
crate,
which allow server implementations to use async fn
for their implementation. The tonic-examples
crate demonstrates more advanced cases with TLS, authentication, load balancing, streaming and more.
Moving forward
Today marks Tonic’s first alpha release, and over the next few months we will be working hard
to ensure that Tonic is ready for production usage. A lot of the implementation has already
been proven in production environments via tower-grpc
. Over the next few months as tokio
0.2
comes closer to a full stable release, Tonic will follow with its own stable releases.
Conclusion
tonic
is now available! There is documentation, examples and
an issue tracker! Please provide any feedback, as we would love to improve this library
any way we can!
Thank you to all the super awesome contributors that have helped over the past few months! Your feedback has been immensely important and valuable!