1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//! # rainier-routing
//!
//! Route declaration and dispatch: the [`Router`] DSL, [`Route`] patterns and
//! constraints, [`GroupAttributes`] for shared prefixes and middleware,
//! [`ResourceController`] for RESTful resources, and [`UrlGenerator`] for
//! building URLs back out of named routes.
//!
//! ```
//! use rainier_container::Container;
//! use rainier_http::{Method, Request};
//! use rainier_routing::{GroupAttributes, Router, UrlGenerator};
//!
//! async fn index() -> &'static str { "posts" }
//! async fn show(request: rainier_routing::Req) -> String {
//! format!("post {}", request.route_param("post").unwrap_or("?"))
//! }
//!
//! # #[tokio::main] async fn main() -> rainier_support::Result<()> {
//! let mut router = Router::new();
//!
//! router.group(GroupAttributes::new().prefix("api").name("api."), |router| {
//! router.get("/posts", index).name("posts.index");
//! router.get("/posts/{post}", show).name("posts.show").where_number("post");
//! });
//!
//! let compiled = router.compile(&Container::new())?;
//! let urls = UrlGenerator::from_routes(compiled.named_routes());
//!
//! assert_eq!(urls.route("api.posts.show", &[("post", "7")])?, "/api/posts/7");
//!
//! let response = compiled
//! .dispatch(Request::builder().method(Method::GET).uri("/api/posts/7").build())
//! .await;
//! assert_eq!(response.status(), 200);
//! # Ok(()) }
//! ```
//!
//! ## Two phases
//!
//! [`Router`] is the *declaration*; [`CompiledRouter`] is the *runtime*.
//! Compiling flattens each route's group and own middleware into one pipeline,
//! builds it once, and rejects duplicate route names at boot rather than on the
//! first request that hits them.
//!
//! Middleware is attached **by value** — `.middleware(Authenticate::new(auth))`,
//! not `.middleware("auth")`. There is no registry to look a name up in and
//! nothing to misspell; see
//! [`MiddlewareStack`](rainier_middleware::MiddlewareStack). Compiling is also
//! where a middleware that needs the container is built, so that failure lands
//! at boot too.
pub use ;
pub use ;
pub use ;
pub use ;
pub use UrlGenerator;
// Re-exported so controllers get the attribute macro without adding the
// dependency themselves.
pub use async_trait;