Expand description
This module provides functionality to aid managing routing requests between Service
s.
§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 it 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().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().await?.call(req).await?;
assert_eq!(res.status(), StatusCode::NOT_FOUND);
assert_eq!(res.into_body(), "");