rama::http::layer

Module validate_request

Expand description

Middleware that validates requests.

§Example

use rama_http::layer::validate_request::ValidateRequestHeaderLayer;
use rama_http::{Body, Request, Response, StatusCode, header::ACCEPT};
use rama_core::service::service_fn;
use rama_core::{Context, Service, Layer};
use rama_core::error::BoxError;

async fn handle(request: Request) -> Result<Response, BoxError> {
    Ok(Response::new(Body::empty()))
}

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

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

let response = service
    .serve(Context::default(), 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(Body::empty())
    .unwrap();

let response = service
    .serve(Context::default(), request)
    .await?;

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

Custom validation can be made by implementing ValidateRequest:

use rama_http::layer::validate_request::{ValidateRequestHeaderLayer, ValidateRequest};
use rama_http::{Body, Request, Response, StatusCode, header::ACCEPT};
use rama_core::service::service_fn;
use rama_core::{Context, Service, Layer};
use rama_core::error::BoxError;

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

impl<S, B> ValidateRequest<S, B> for MyHeader
    where
        S: Clone + Send + Sync + 'static,
        B: Send + 'static,
{
    type ResponseBody = Body;

    async fn validate(
        &self,
        ctx: Context<S>,
        req: Request<B>,
    ) -> Result<(Context<S>, Request<B>), Response<Self::ResponseBody>> {
        // validate the request...
    }
}

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


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


let response = service
    .serve(Context::default(), request)
    .await?;

Or using a closure:

use bytes::Bytes;
use rama_http::{Body, Request, Response, StatusCode, header::ACCEPT};
use rama_http::layer::validate_request::{ValidateRequestHeaderLayer, ValidateRequest};
use rama_core::service::service_fn;
use rama_core::{Context, Service, Layer};
use rama_core::error::BoxError;

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

let service = (
    ValidateRequestHeaderLayer::custom_fn(|request: Request| async move {
        // Validate the request
    }),
).layer(service_fn(handle));


let response = service
    .serve(Context::default(), request)
    .await?;

Structs§

Traits§