Skip to main content

Endpoint

Trait Endpoint 

Source
pub trait Endpoint: Send {
    type Error: HttpError;

    // Required method
    fn respond(
        &mut self,
        request: &mut Request,
    ) -> impl Future<Output = Result<Response, Self::Error>> + Send;
}
Expand description

A trait for types that can handle HTTP requests and generate responses.

Endpoints represent the final destination in the HTTP request processing pipeline. They receive a mutable reference to the request (allowing them to consume the body or modify headers) and return a response or error.

§Implementation Notes

  • Endpoints must be Send to work in async contexts
  • The request parameter is mutable, allowing body consumption and header modification
  • Implementations should handle errors gracefully and return appropriate HTTP status codes
  • Endpoints can be combined with middleware for additional functionality

§Examples

§Simple Text Response

use http_kit::{Request, Response, Endpoint, Body, BoxHttpError};

struct GreetingEndpoint {
    name: String,
}

impl Endpoint for GreetingEndpoint {
    type Error = BoxHttpError;
    async fn respond(&mut self, _request: &mut Request) -> Result<Response, Self::Error> {
        let message = format!("Hello, {}!", self.name);
        Ok(Response::new(Body::from_bytes(message)))
    }
}

§JSON API Endpoint

use http::StatusCode;
use http_kit::{Request, Response, Result, Endpoint, Body, HttpError, BodyError};
use serde::{Serialize, Deserialize};
use thiserror::Error;

#[derive(Debug, Error)]
enum ApiError {
    #[error("json error: {0}")]
    Json(#[from] serde_json::Error),
    #[error("body error: {0}")]
    Body(#[from] BodyError),
}

impl HttpError for ApiError {
    fn status(&self) -> StatusCode {
        match self {
            Self::Json(_) => StatusCode::BAD_REQUEST,
            Self::Body(_) => StatusCode::INTERNAL_SERVER_ERROR,
        }
    }
}

#[derive(Serialize, Deserialize)]
struct User { name: String, age: u32 }

struct UserEndpoint;

impl Endpoint for UserEndpoint {
    type Error = ApiError;
    async fn respond(&mut self, request: &mut Request) -> Result<Response, Self::Error> {
        match request.method().as_str() {
            "GET" => {
                let user = User { name: "Alice".into(), age: 30 };
                let body = Body::from_json(&user)?;
                Ok(Response::new(body))
            }
            "POST" => {
                let user: User = request
                    .body_mut()
                    .into_json()
                    .await?;
                // Process user...
                let body = Body::from_json(&user)?;
                Ok(Response::new(body))
            }
            _ => Ok(Response::new(Body::from_bytes("Method Not Allowed")))
        }
    }
}

Required Associated Types§

Source

type Error: HttpError

The error type returned by this endpoint.

Required Methods§

Source

fn respond( &mut self, request: &mut Request, ) -> impl Future<Output = Result<Response, Self::Error>> + Send

Processes an HTTP request and generates a response.

This method receives a mutable reference to the request, allowing it to:

  • Consume the request body with take_body() or similar methods
  • Read headers, URI, method, and other request metadata
  • Modify request state if needed (though this is less common)

The method should return either a successful Response or an Error with an appropriate HTTP status code.

§Arguments
  • request - Mutable reference to the HTTP request being processed
§Examples
use http_kit::{Request, Response, Endpoint, Body, BoxHttpError};

struct StatusEndpoint;

impl Endpoint for StatusEndpoint {
    type Error = BoxHttpError;
    async fn respond(&mut self, request: &mut Request) -> Result<Response,Self::Error> {
        let status = format!("Method: {}, URI: {}", request.method(), request.uri());
        Ok(Response::new(Body::from_bytes(status)))
    }
}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl<E: Endpoint> Endpoint for &mut E

Source§

type Error = <E as Endpoint>::Error

Source§

async fn respond( &mut self, request: &mut Request, ) -> Result<Response, Self::Error>

Source§

impl<E: Endpoint> Endpoint for Box<E>

Source§

type Error = <E as Endpoint>::Error

Source§

async fn respond( &mut self, request: &mut Request, ) -> Result<Response, Self::Error>

Implementors§