Skip to main content

rama_http/layer/validate_request/
mod.rs

1//! Middleware that validates requests.
2//!
3//! # Example
4//!
5//! ```
6//! use rama_http::layer::validate_request::ValidateRequestHeaderLayer;
7//! use rama_http::{Body, Request, Response, StatusCode, header::ACCEPT};
8//! use rama_core::service::service_fn;
9//! use rama_core::{Service, Layer};
10//! use rama_core::error::BoxError;
11//!
12//! async fn handle(request: Request) -> Result<Response, BoxError> {
13//!     Ok(Response::new(Body::empty()))
14//! }
15//!
16//! # #[tokio::main]
17//! # async fn main() -> Result<(), BoxError> {
18//! let mut service = (
19//!     // Require the `Accept` header to be `application/json`, `*/*` or `application/*`
20//!     ValidateRequestHeaderLayer::try_accept_for_str("application/json").unwrap(),
21//! ).into_layer(service_fn(handle));
22//!
23//! // Requests with the correct value are allowed through
24//! let request = Request::builder()
25//!     .header(ACCEPT, "application/json")
26//!     .body(Body::empty())
27//!     .unwrap();
28//!
29//! let response = service
30//!     .serve(request)
31//!     .await?;
32//!
33//! assert_eq!(StatusCode::OK, response.status());
34//!
35//! // Requests with an invalid value get a `406 Not Acceptable` response
36//! let request = Request::builder()
37//!     .header(ACCEPT, "text/strings")
38//!     .body(Body::empty())
39//!     .unwrap();
40//!
41//! let response = service
42//!     .serve(request)
43//!     .await?;
44//!
45//! assert_eq!(StatusCode::NOT_ACCEPTABLE, response.status());
46//! # Ok(())
47//! # }
48//! ```
49//!
50//! Custom validation can be made by implementing [`ValidateRequest`]:
51//!
52//! ```
53//! use rama_http::layer::validate_request::{ValidateRequestHeaderLayer, ValidateRequest};
54//! use rama_http::{Body, Request, Response, StatusCode, header::ACCEPT};
55//! use rama_core::service::service_fn;
56//! use rama_core::{Service, Layer};
57//! use rama_core::error::BoxError;
58//!
59//! #[derive(Clone, Copy)]
60//! pub struct MyHeader { /* ...  */ }
61//!
62//! impl<B> ValidateRequest<B> for MyHeader
63//!     where
64//!         B: Send + 'static,
65//! {
66//!     type ResponseBody = Body;
67//!
68//!     async fn validate(
69//!         &self,
70//!         req: Request<B>,
71//!     ) -> Result<Request<B>, Response<Self::ResponseBody>> {
72//!         // validate the request...
73//!         # Ok::<_, Response>(req)
74//!     }
75//! }
76//!
77//! async fn handle(request: Request) -> Result<Response, BoxError> {
78//!     # Ok(Response::builder().body(Body::empty()).unwrap())
79//!     // ...
80//! }
81//!
82//!
83//! # #[tokio::main]
84//! # async fn main() -> Result<(), BoxError> {
85//! let service = (
86//!     // Validate requests using `MyHeader`
87//!     ValidateRequestHeaderLayer::custom(MyHeader { /* ... */ }),
88//! ).into_layer(service_fn(handle));
89//!
90//! # let request = Request::builder()
91//! #     .body(Body::empty())
92//! #     .unwrap();
93//!
94//! let response = service
95//!     .serve(request)
96//!     .await?;
97//!
98//! # Ok(())
99//! # }
100//! ```
101//!
102//! Or using a closure:
103//!
104//! ```
105//! use rama_core::bytes::Bytes;
106//! use rama_http::{Body, Request, Response, StatusCode, header::ACCEPT};
107//! use rama_http::layer::validate_request::{ValidateRequestHeaderLayer, ValidateRequest};
108//! use rama_core::service::service_fn;
109//! use rama_core::{Service, Layer};
110//! use rama_core::error::BoxError;
111//!
112//! async fn handle(request: Request) -> Result<Response, BoxError> {
113//!     # Ok(Response::builder().body(Body::empty()).unwrap())
114//!     // ...
115//! }
116//!
117//! # #[tokio::main]
118//! # async fn main() -> Result<(), BoxError> {
119//! let service = (
120//!     ValidateRequestHeaderLayer::custom_fn(async |request: Request| {
121//!         // Validate the request
122//!         # Ok::<_, Response>(request)
123//!     }),
124//! ).into_layer(service_fn(handle));
125//!
126//! # let request = Request::builder()
127//! #     .body(Body::empty())
128//! #     .unwrap();
129//!
130//! let response = service
131//!     .serve(request)
132//!     .await?;
133//!
134//! # Ok(())
135//! # }
136//! ```
137
138mod accept_header;
139mod validate;
140mod validate_fn;
141mod validate_request_header;
142
143#[doc(inline)]
144pub use accept_header::AcceptHeader;
145#[doc(inline)]
146pub use validate::ValidateRequest;
147#[doc(inline)]
148pub use validate_fn::{BoxValidateRequestFn, ValidateRequestFn};
149#[doc(inline)]
150pub use validate_request_header::{ValidateRequestHeader, ValidateRequestHeaderLayer};