hyper v0.13

After a few months of alpha development, the final release of hyper v0.13.0 is now ready! hyper is a maturing HTTP library written in Rust, already one of the fastest out there, and trusted by many for its correctness.

The highlights of this release:

Full async / await support.

/ support. Tokio v0.2 upgrade.

Adopting tower::Service .

async / await

The premise of async and await in Rust is to allow writing code that uses Future s in a similar style to “blocking” code. No more combinators, no more “callbacks”, just slap .await on the end of the expression. For instance, here’s how we can use the Client :

#[tokio::main] async fn main() -> Result { let client = Client::new(); let mut resp = client.get("http://httpbin.org/ip".parse()?).await?; println!("Status: {}", resp.status()); println!("Headers: {:#?}

", resp.headers()); while let Some(chunk) = resp.body_mut().data().await { stdout().write_all(&chunk?).await?; } Ok(()) }

Connecting, writing the request, receiving the response, streaming the body, and writing to stdout can all be done without “blocking” the thread. Instead, with the use of await , just that future will make as much progress as it can without blocking, and then go to a pending state and register a notification when more progress could be made. And yet, it looks just like regular “blocking” code. This should hugely improve the ergonomics of writing server code that scales under load.

Tokio v0.2

Tokio is a phenomenal async IO runtime for Rust, and hyper has built-in support by default. The Tokio v0.2 upgrade includes async / await support, a significant scheduler improvement, and even faster compile times.

Tower Services

Tower is an RPC design that builds off Twitter’s “your server as a function”. It defines the base Service trait, which handles some request-like value, and asynchronously returns a response-like value. The tower-service crate is minimal, and protocol-agnostic. Our hope is others in the ecosystem can be just use Service and http , and not have to depend directly on hyper.

An additional benefit of integrating with Tower is being able to make use of many of the middleware we’ve already developed.

Server middleware: let svc = ServiceBuilder::new() // Reject the request early if concurrency limit is hit .load_shed() // Only allow 1,000 requests in flight at a time .concurrency_limit(1_000) // Cancel requests that hang too long .timeout(Duration::from_secs(30)) // All wrapped around your application logic .service(your_app_service);

Or wrapping a Client: let svc = ServiceBuilder::new() // Retry requests depending on the responses or errors .retry(your_retry_policy) // Cancel when the server takes too long .timeout(Duration::from_secs(5) // Load balance using P2C .layer(p2c::peak_ewma(dns_resolver)) // Wrapping a hyper::Client .service(hyper_client);

Additionally, most async fn(In) -> Out things in hyper are now just a Service . This means you can easily add these middleware to custom resolvers or connectors, for instance. Uses include adding a timeout or whitelist to a resolver.

v0.13.0

This probably the most exciting release of hyper yet. It’s all thanks to the 30+ contributors tireless efforts this release that we’ve gotten this far. Our production users continue to help us improve hyper’s correctness, performance, and features. The current goal is that we can finish up the remaining design questions and release hyper 1.0 in the middle of 2020.

To see even more details, check out the v0.13.0 changelog!