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 std::task::{Context, Poll};
# use tower_service::Service;
# use futures_util::future::{ready, Ready, poll_fn};
# use tower::steer::Steer;
# use tower::service_fn;
# use tower::util::BoxService;
# use tower::ServiceExt;
# use std::convert::Infallible;
use http::{Request, Response, StatusCode, Method};
# #[tokio::main]
# async fn main() -> Result<(), Box<dyn std::error::Error>> {
let root = service_fn(|req: Request<String>| async move {
# assert_eq!(req.uri().path(), "/");
let res = Response::new("Hello, World!".to_string());
Ok::<_, Infallible>(res)
});
let root = BoxService::new(root);
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)
});
let not_found = BoxService::new(not_found);
let mut svc = Steer::new(
vec![root, not_found],
|req: &Request<String>, _services: &[_]| {
if req.method() == Method::GET && req.uri().path() == "/" {
0 } else {
1 }
},
);
let req = Request::get("/").body(String::new()).unwrap();
let res = svc.ready().await?.call(req).await?;
assert_eq!(res.into_body(), "Hello, World!");
let req = Request::get("/does/not/exist").body(String::new()).unwrap();
let res = svc.ready().await?.call(req).await?;
assert_eq!(res.status(), StatusCode::NOT_FOUND);
assert_eq!(res.into_body(), "");
#
# Ok(())
# }