[][src]Module tower::steer

This is supported on crate feature steer only.

This module provides functionality to aid managing routing requests between Services.

Example

Steer can for example be used to create a router, akin to what you might find in web frameworks.

Here, GET / will be sent to the root service, while all other requests go to not_found.

use http::{Request, Response, StatusCode, Method};

// service that responds to `GET /`
let root = service_fn(|req: Request<String>| async move {
    let res = Response::new("Hello, World!".to_string());
    Ok::<_, Infallible>(res)
});
// we have to box the service so its type gets erased and we can put in a `Vec` with other
// services
let root = BoxService::new(root);

// service that responds with `404 Not Found` to all requests
let not_found = service_fn(|req: Request<String>| async move {
    let res = Response::builder()
        .status(StatusCode::NOT_FOUND)
        .body(String::new())
        .expect("response is valid");
    Ok::<_, Infallible>(res)
});
// box that as well
let not_found = BoxService::new(not_found);

let mut svc = Steer::new(
    // all services we route between
    vec![root, not_found],
    // how we pick which service to send the request to
    |req: &Request<String>, _services: &[_]| {
        if req.method() == Method::GET && req.uri().path() == "/" {
            0 // index of `root`
        } else {
            1 // index of `not_found`
        }
    },
);

// this request will get sent to `root`
let req = Request::get("/").body(String::new()).unwrap();
let res = svc.ready_and().await?.call(req).await?;
assert_eq!(res.into_body(), "Hello, World!");

// this request will get sent to `not_found`
let req = Request::get("/does/not/exist").body(String::new()).unwrap();
let res = svc.ready_and().await?.call(req).await?;
assert_eq!(res.status(), StatusCode::NOT_FOUND);
assert_eq!(res.into_body(), "");

Structs

Steer

Steer manages a list of Services which all handle the same type of request.

Traits

Picker

This is how callers of Steer tell it which Service a Req corresponds to.