pub trait EndpointExt: IntoEndpoint {
Show 16 methods fn boxed<'a>(self) -> BoxEndpoint<'a, <Self::Endpoint as Endpoint>::Output>
    where
        Self: Sized + 'a
, { ... } fn with<T>(self, middleware: T) -> T::Output
    where
        T: Middleware<Self::Endpoint>,
        Self: Sized
, { ... } fn with_if<T>(
        self,
        enable: bool,
        middleware: T
    ) -> EitherEndpoint<Self, T::Output>
    where
        T: Middleware<Self::Endpoint>,
        Self: Sized
, { ... } fn data<T>(self, data: T) -> AddDataEndpoint<Self::Endpoint, T>
    where
        T: Clone + Send + Sync + 'static,
        Self: Sized
, { ... } fn data_opt<T>(
        self,
        data: Option<T>
    ) -> EitherEndpoint<AddDataEndpoint<Self::Endpoint, T>, Self>
    where
        T: Clone + Send + Sync + 'static,
        Self: Sized
, { ... } fn before<F, Fut>(self, f: F) -> Before<Self, F>
    where
        F: Fn(Request) -> Fut + Send + Sync,
        Fut: Future<Output = Result<Request>> + Send,
        Self: Sized
, { ... } fn after<F, Fut, T>(self, f: F) -> After<Self::Endpoint, F>
    where
        F: Fn(Result<<Self::Endpoint as Endpoint>::Output>) -> Fut + Send + Sync,
        Fut: Future<Output = Result<T>> + Send,
        T: IntoResponse,
        Self: Sized
, { ... } fn around<F, Fut, R>(self, f: F) -> Around<Self::Endpoint, F>
    where
        F: Fn(Arc<Self::Endpoint>, Request) -> Fut + Send + Sync + 'static,
        Fut: Future<Output = Result<R>> + Send + 'static,
        R: IntoResponse,
        Self: Sized
, { ... } fn map_to_response(self) -> MapToResponse<Self::Endpoint>
    where
        Self: Sized
, { ... } fn to_response(self) -> ToResponse<Self::Endpoint>
    where
        Self: Sized
, { ... } fn map<F, Fut, R, R2>(self, f: F) -> Map<Self::Endpoint, F>
    where
        F: Fn(R) -> Fut + Send + Sync,
        Fut: Future<Output = R2> + Send,
        R: IntoResponse,
        R2: IntoResponse,
        Self: Sized,
        Self::Endpoint: Endpoint<Output = R> + Sized
, { ... } fn and_then<F, Fut, R, R2>(self, f: F) -> AndThen<Self::Endpoint, F>
    where
        F: Fn(R) -> Fut + Send + Sync,
        Fut: Future<Output = Result<R2>> + Send,
        R: IntoResponse,
        R2: IntoResponse,
        Self: Sized,
        Self::Endpoint: Endpoint<Output = R> + Sized
, { ... } fn catch_all_error<F, Fut, R>(self, f: F) -> CatchAllError<Self, F, R>
    where
        F: Fn(Error) -> Fut + Send + Sync,
        Fut: Future<Output = R> + Send,
        R: IntoResponse + Send,
        Self: Sized + Sync
, { ... } fn catch_error<F, Fut, R, ErrType>(
        self,
        f: F
    ) -> CatchError<Self, F, R, ErrType>
    where
        F: Fn(ErrType) -> Fut + Send + Sync,
        Fut: Future<Output = R> + Send,
        R: IntoResponse + Send + Sync,
        ErrType: Error + Send + Sync + 'static,
        Self: Sized
, { ... } fn inspect_all_err<F>(self, f: F) -> InspectAllError<Self, F>
    where
        F: Fn(&Error) + Send + Sync,
        Self: Sized
, { ... } fn inspect_err<F, ErrType>(self, f: F) -> InspectError<Self, F, ErrType>
    where
        F: Fn(&ErrType) + Send + Sync,
        ErrType: Error + Send + Sync + 'static,
        Self: Sized
, { ... }
}
Expand description

Extension trait for Endpoint.

Provided Methods

Wrap the endpoint in a Box.

Use middleware to transform this endpoint.

Example
use poem::{
    get, handler, http::StatusCode, middleware::AddData, test::TestClient, web::Data, Endpoint,
    EndpointExt, Request, Route,
};

#[handler]
async fn index(Data(data): Data<&i32>) -> String {
    format!("{}", data)
}

let app = Route::new().at("/", get(index)).with(AddData::new(100i32));
let cli = TestClient::new(app);

let resp = cli.get("/").send().await;
resp.assert_status_is_ok();
resp.assert_text("100").await;

if enable is true then use middleware to transform this endpoint.

Example
use poem::{
    get, handler,
    http::{StatusCode, Uri},
    middleware::AddData,
    test::TestClient,
    web::Data,
    Endpoint, EndpointExt, Request, Route,
};

#[handler]
async fn index(data: Option<Data<&i32>>) -> String {
    match data {
        Some(data) => data.0.to_string(),
        None => "none".to_string(),
    }
}

let app = Route::new()
    .at("/a", get(index).with_if(true, AddData::new(100i32)))
    .at("/b", get(index).with_if(false, AddData::new(100i32)));
let cli = TestClient::new(app);

let resp = cli.get("/a").send().await;
resp.assert_status_is_ok();
resp.assert_text("100").await;

let resp = cli.get("/b").send().await;
resp.assert_status_is_ok();
resp.assert_text("none").await;

Attach a state data to the endpoint, similar to with(AddData(T)).

Example
use poem::{
    handler, http::StatusCode, test::TestClient, web::Data, Endpoint, EndpointExt, Request,
};

#[handler]
async fn index(data: Data<&i32>) -> String {
    format!("{}", data.0)
}

let resp = TestClient::new(index.data(100i32)).get("/").send().await;
resp.assert_status_is_ok();
resp.assert_text("100").await;

if data is Some(T) then attach the value to the endpoint.

Maps the request of this endpoint.

Example
use poem::{
    handler, http::StatusCode, test::TestClient, Endpoint, EndpointExt, Error, Request, Result,
};

#[handler]
async fn index(data: String) -> String {
    data
}

let mut resp = index
    .before(|mut req| async move {
        req.set_body("abc");
        Ok(req)
    })
    .call(Request::default())
    .await
    .unwrap();
assert_eq!(resp.take_body().into_string().await.unwrap(), "abc");

Maps the output of this endpoint.

Example
use poem::{handler, http::StatusCode, Endpoint, EndpointExt, Error, Request, Result};

#[handler]
async fn index() -> &'static str {
    "abc"
}

let mut resp = index
    .after(|res| async move {
        match res {
            Ok(resp) => Ok(resp.into_body().into_string().await.unwrap() + "def"),
            Err(err) => Err(err),
        }
    })
    .call(Request::default())
    .await
    .unwrap();
assert_eq!(resp, "abcdef");

Maps the request and response of this endpoint.

Example
use poem::{
    handler,
    http::{HeaderMap, HeaderValue, StatusCode},
    Endpoint, EndpointExt, Error, Request, Result,
};

#[handler]
async fn index(headers: &HeaderMap) -> String {
    headers
        .get("x-value")
        .and_then(|value| value.to_str().ok())
        .unwrap()
        .to_string()
        + ","
}

let mut resp = index
    .around(|ep, mut req| async move {
        req.headers_mut()
            .insert("x-value", HeaderValue::from_static("hello"));
        let mut resp = ep.call(req).await?;
        Ok(resp.take_body().into_string().await.unwrap() + "world")
    })
    .call(Request::default())
    .await
    .unwrap();
assert_eq!(resp, "hello,world");

Convert the output of this endpoint into a response. Response.

Example
use poem::{
    endpoint::make, http::StatusCode, Endpoint, EndpointExt, Error, Request, Response, Result,
};

let ep1 = make(|_| async { "hello" }).map_to_response();
let ep2 = make(|_| async { Err::<(), Error>(Error::from_status(StatusCode::BAD_REQUEST)) })
    .map_to_response();

let resp = ep1.call(Request::default()).await.unwrap();
assert_eq!(resp.into_body().into_string().await.unwrap(), "hello");

let err = ep2.call(Request::default()).await.unwrap_err();
assert_eq!(err.into_response().status(), StatusCode::BAD_REQUEST);

Convert the output of this endpoint into a response. Response.

NOTE: Unlike EndpointExt::map_to_response, when an error occurs, it will also convert the error into a response object, so this endpoint will just returns Ok(Response).

Example
use poem::{
    endpoint::make, http::StatusCode, Endpoint, EndpointExt, Error, Request, Response, Result,
};

let ep1 = make(|_| async { "hello" }).to_response();
let ep2 = make(|_| async { Err::<(), Error>(Error::from_status(StatusCode::BAD_REQUEST)) })
    .to_response();

let resp = ep1.call(Request::default()).await.unwrap();
assert_eq!(resp.into_body().into_string().await.unwrap(), "hello");

let resp = ep2.call(Request::default()).await.unwrap();
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);

Maps the response of this endpoint.

Example
use poem::{
    endpoint::make, http::StatusCode, Endpoint, EndpointExt, Error, Request, Response, Result,
};

let ep = make(|_| async { "hello" }).map(|value| async move { format!("{}, world!", value) });

let mut resp: String = ep.call(Request::default()).await.unwrap();
assert_eq!(resp, "hello, world!");

Calls f if the result is Ok, otherwise returns the Err value of self.

Example
use poem::{
    endpoint::make, http::StatusCode, Endpoint, EndpointExt, Error, Request, Response, Result,
};

let ep1 = make(|_| async { "hello" })
    .and_then(|value| async move { Ok(format!("{}, world!", value)) });
let ep2 = make(|_| async { Err::<String, _>(Error::from_status(StatusCode::BAD_REQUEST)) })
    .and_then(|value| async move { Ok(format!("{}, world!", value)) });

let resp: String = ep1.call(Request::default()).await.unwrap();
assert_eq!(resp, "hello, world!");

let err: Error = ep2.call(Request::default()).await.unwrap_err();
assert_eq!(err.into_response().status(), StatusCode::BAD_REQUEST);

Catch all errors and convert it into a response.

Example
use http::Uri;
use poem::{
    handler, http::StatusCode, web::Json, Endpoint, EndpointExt, Error, IntoResponse, Request,
    Response, Route,
};
use serde::Serialize;

#[handler]
async fn index() {}

let app = Route::new()
    .at("/index", index)
    .catch_all_error(custom_error);

#[derive(Serialize)]
struct ErrorResponse {
    message: String,
}

async fn custom_error(err: Error) -> impl IntoResponse {
    Json(ErrorResponse {
        message: err.to_string(),
    })
}

let resp = app
    .call(Request::builder().uri(Uri::from_static("/abc")).finish())
    .await
    .unwrap();
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(
    resp.into_body().into_string().await.unwrap(),
    "{\"message\":\"not found\"}"
);

Catch the specified type of error and convert it into a response.

Example
use http::Uri;
use poem::{
    error::NotFoundError, handler, http::StatusCode, Endpoint, EndpointExt, IntoResponse,
    Request, Response, Route,
};

#[handler]
async fn index() {}

let app = Route::new().at("/index", index).catch_error(custom_404);

async fn custom_404(_: NotFoundError) -> impl IntoResponse {
    "custom not found".with_status(StatusCode::NOT_FOUND)
}


let resp = app
    .call(Request::builder().uri(Uri::from_static("/abc")).finish())
    .await
    .unwrap();
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
assert_eq!(
    resp.into_body().into_string().await.unwrap(),
    "custom not found"
);

Does something with each error.

Example
use poem::{handler, EndpointExt, Route};

#[handler]
fn index() {}

let app = Route::new().at("/", index).inspect_all_err(|err| {
    println!("error: {}", err);
});

Does something with each specified error type.

Example
use poem::{error::NotFoundError, handler, EndpointExt, Route};

#[handler]
fn index() {}

let app = Route::new()
    .at("/", index)
    .inspect_err(|err: &NotFoundError| {
        println!("error: {}", err);
    });

Implementors