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, Result, Endpoint, Body, Error};

struct GreetingEndpoint {
    name: String,
}

impl Endpoint for GreetingEndpoint {
    type Error = Error;
    async fn respond(&mut self, _request: &mut Request) -> Result<Response> {
        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) -> Option<StatusCode> {
        match self {
            Self::Json(_) => Some(StatusCode::BAD_REQUEST),
            Self::Body(_) => Some(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, Result, Endpoint, Body, Error};

struct StatusEndpoint;

impl Endpoint for StatusEndpoint {
    type Error = Error;
    async fn respond(&mut self, request: &mut Request) -> Result<Response> {
        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", so this trait is not object safe.

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§