Rustlings: Live!

Fast and safe HTTP for the Rust language.

hyper

hyper

  • A Client for talking to web services.
  • A Server for building those web services.
  • Blazing fast*
  • High concurrency with non-blocking sockets.
  • HTTP/1 and HTTP/2 support.

Rust web frameworks

Supported Runtime Async/Await Support
actix-web tokio Y
rocket tokio Y (built on hyper)
warp async-std Y (built on hyper)
tide tokio Y
tower web tokio Y (built on hyper)

Rust web frameworks

Supported Runtime Async/Await Support
actix-web tokio Y
rocket tokio Y (built on hyper)
warp async-std Y (built on hyper)
tide tokio Y
tower web tokio Y (built on hyper)

Let's make an endpoint

  1. Make a service
  2. Start a server

1. Make a service

A Service is a trait representing an asynchronous function of a request to a response.

 

Similar to:

async fn(Request) -> Result<Response, Error>.

1. Make a service

(Request<Body>) -> Result<Response<Body>, Infallible>

The error type for errors that can never happen.

pub enum Infallible {}

pub enum Result<T, E> {

    Ok(T),

    Err(E),

}

use hyper::{Body, Request, Response};

1. Make a service

async fn hello_world(_req: Request<Body>) -> Result<Response<Body>, Infallible> {

    Ok(Response::new("hello world".into()))

}

Let's make an endpoint

  1. Make a service
  2. Connect service to server

2. Connect service to server

#[tokio::main]
async fn main() {
  let make_svc = make_service_fn(|_conn| async {
    Ok::<_, Infallible>(service_fn(hello_world))
  });
  let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

  let server = Server::bind(&addr).serve(make_svc);

  println!("Listening on http://{}", addr);

  server.await?;
    Ok(());
}

1. Make a service

HttpService

This is blanketly implemented for all types that implement Service<http::Request<B1>, Response = http::Response<B2>>.
 

MakeService

When a Service returns a new Service as its "response", we consider it a MakeService. Again, blanketly implemented in those cases.
 

MakeConnection

MakeConnection: A Service that returns a "connection", a type that implements AsyncRead and AsyncWrite.

2. Connect service to server

#[tokio::main]
async fn main() {
  let make_svc = make_service_fn(|_conn| async {
    Ok::<_, Infallible>(service_fn(hello_world))
  });
  let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

  let server = Server::bind(&addr).serve(make_svc);

  println!("Listening on http://{}", addr);

  server.await?;
    Ok(());
}

A helper to convert a function that
returns a Response into a `Service`.

Make Service

Since a Service is bound to a single connection, a Server needs a way to make them as it accepts connections. This is what a MakeService does.

Make Service

pub fn make_service_fn<F, Target, Ret>(f: F) -> MakeServiceFn<F> 
F: FnMut(&Target) -> Ret,
Ret: Future,
FnMut can change the environment because it mutably borrows values.
F: FnMut(&Target) -> Ret,
A future represents an asynchronous computation.

2. Connect service to server

#[tokio::main]
async fn main() {
  let make_svc = make_service_fn(|_conn| async {
    ...
  });
  let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

  let server = Server::bind(&addr).serve(make_svc);

  println!("Listening on http://{}", addr);

  server.await?;
    Ok(());
}

Bind to 127.0.0.1:3000 and serve our make service

2. Connect service to server

#[tokio::main]
async fn main() {
  let make_svc = make_service_fn(|_conn| async {
    ...
  });
  let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
  let server = Server::bind(&addr).serve(make_svc);

  println!("Listening on http://{}", addr);

  server.await?;

  Ok(());
}

Infinitely run

Made with Slides.com