Module validate_request

Source
Available on crate feature validate-request only.
Expand description

Middleware that validates requests.

§Example

use tower_http::validate_request::ValidateRequestHeaderLayer;
use http::{Request, Response, StatusCode, header::ACCEPT};
use http_body_util::Full;
use bytes::Bytes;
use tower::{Service, ServiceExt, ServiceBuilder, service_fn, BoxError};

async fn handle(request: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, BoxError> {
    Ok(Response::new(Full::default()))
}

let mut service = ServiceBuilder::new()
    // Require the `Accept` header to be `application/json`, `*/*` or `application/*`
    .layer(ValidateRequestHeaderLayer::accept("application/json"))
    .service_fn(handle);

// Requests with the correct value are allowed through
let request = Request::builder()
    .header(ACCEPT, "application/json")
    .body(Full::default())
    .unwrap();

let response = service
    .ready()
    .await?
    .call(request)
    .await?;

assert_eq!(StatusCode::OK, response.status());

// Requests with an invalid value get a `406 Not Acceptable` response
let request = Request::builder()
    .header(ACCEPT, "text/strings")
    .body(Full::default())
    .unwrap();

let response = service
    .ready()
    .await?
    .call(request)
    .await?;

assert_eq!(StatusCode::NOT_ACCEPTABLE, response.status());

Custom validation can be made by implementing ValidateRequest:

use tower_http::validate_request::{ValidateRequestHeaderLayer, ValidateRequest};
use http::{Request, Response, StatusCode, header::ACCEPT};
use http_body_util::Full;
use tower::{Service, ServiceExt, ServiceBuilder, service_fn, BoxError};
use bytes::Bytes;

#[derive(Clone, Copy)]
pub struct MyHeader { /* ...  */ }

impl<B> ValidateRequest<B> for MyHeader {
    type ResponseBody = Full<Bytes>;

    fn validate(
        &mut self,
        request: &mut Request<B>,
    ) -> Result<(), Response<Self::ResponseBody>> {
        // validate the request...
    }
}

async fn handle(request: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, BoxError> {
    Ok(Response::new(Full::default()))
}


let service = ServiceBuilder::new()
    // Validate requests using `MyHeader`
    .layer(ValidateRequestHeaderLayer::custom(MyHeader { /* ... */ }))
    .service_fn(handle);

Or using a closure:

use tower_http::validate_request::{ValidateRequestHeaderLayer, ValidateRequest};
use http::{Request, Response, StatusCode, header::ACCEPT};
use bytes::Bytes;
use http_body_util::Full;
use tower::{Service, ServiceExt, ServiceBuilder, service_fn, BoxError};

async fn handle(request: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, BoxError> {
    // ...
}

let service = ServiceBuilder::new()
    .layer(ValidateRequestHeaderLayer::custom(|request: &mut Request<Full<Bytes>>| {
        // Validate the request
    }))
    .service_fn(handle);

Structs§

AcceptHeader
Type that performs validation of the Accept header.
ResponseFuture
Response future for ValidateRequestHeader.
ValidateRequestHeader
Middleware that validates requests.
ValidateRequestHeaderLayer
Layer that applies ValidateRequestHeader which validates all requests.

Traits§

ValidateRequest
Trait for validating requests.