To start with, we’ll just get a simple GET
request to a webpage working,
so we can see all the moving parts. First, we need our dependencies.
Let’s tell Cargo about our dependencies by having this in the Cargo.toml.
Dependencies
[dependencies]
hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1", features = ["full"] }
Now, we need to import pieces to use from our dependencies:
# extern crate hyper;
use hyper::Client;
# fn main() {}
Runtime
Now, we’ll make a request in the main
of our program. This may seem
like a bit of work just to make a simple request, and you’d be correct,
but the point here is just to show all the setup required. Once you have this,
you are set to make thousands of client requests efficiently.
We have to setup some sort of runtime. By default, hyper can make use of the Tokio runtime. If you’ve never used futures in Rust before, you may wish to read through Tokio’s guide on Futures.
# extern crate tokio;
# mod no_run {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// This is where we will setup our HTTP client requests.
Ok(())
}
# }
# fn main() {}
GET
We can now create a hyper Client
that will be registered to our runtime.
Calling client.get
returns a Future
that will eventually be fulfilled with a
Response
.
# extern crate hyper;
# use hyper::Client;
# async fn run() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Still inside `async fn main`...
let client = Client::new();
// Parse an `http::Uri`...
let uri = "http://httpbin.org/ip".parse()?;
// Await the response...
let mut resp = client.get(uri).await?;
println!("Response: {}", resp.status());
# Ok(())
# }
# fn main() {}
Response bodies
Bodies in hyper are always streamed asynchronously. But it’s easy to await
for each chunk as it comes in! We’ll make use of the HttpBody
trait.
We’ll also simply write the body to stdout
. So, some new imports:
# extern crate hyper;
# extern crate tokio;
use hyper::body::HttpBody as _;
use tokio::io::{stdout, AsyncWriteExt as _};
# extern crate hyper;
# extern crate tokio;
# use hyper::Client;
# use hyper::body::HttpBody as _;
# use tokio::io::{stdout, AsyncWriteExt as _};
# async fn run() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Previously...
let client = Client::new();
let uri = "http://httpbin.org/ip".parse()?;
let mut resp = client.get(uri).await?;
println!("Response: {}", resp.status());
// And now...
while let Some(chunk) = resp.body_mut().data().await {
stdout().write_all(&chunk?).await?;
}
#
# Ok(())
# }
# fn main() {}
And that’s it! You can see the full example here.