A small, composable async HTTP framework built on Hyper.
This crate provides a minimal set of primitives for building HTTP servers with explicit control flow and predictable composition.
The core ideas are:
- Handlers as async functions: request handling logic is expressed as ordinary async functions or closures.
- Structured early exit: control flow is modeled explicitly using [
Flow], rather than conflating errors with responses. - Composable pipelines: handlers can be chained together to form request processing pipelines.
The crate intentionally avoids hidden middleware stacks, global state, or implicit error handling. All control flow is explicit and type-driven.
Core Types
- [
Server]: A thin wrapper around Hyper that accepts TCP connections and dispatches HTTP requests to a handler. - [
Handler]: An asynchronous function-like trait that processes inputs and shared state. - [
Flow]: A control-flow type used to model continuation or early exit. - [
Request] and [Response]: Lightweight HTTP request/response types.
Control Flow Model
Instead of using Result<T, E> for request handling, this crate uses
[Flow<C, E>]:
- [
Flow::Continue] represents successful continuation. - [
Flow::Exit] represents an intentional early exit.
An exit is not necessarily an error; it is simply a signal that no further handlers should run and a response should be returned immediately.
Because [Flow] implements the ? operator, early exits can be propagated
ergonomically through handler chains.
Handler Composition
Handlers can be chained using [Handler::then]:
let handler = authenticate
.then(authorize)
.then(handle_request);
Each handler receives the output of the previous one. If any handler exits early, the remaining handlers are skipped and the exit value is returned as a response.
Example
async fn handler(req: Request, state: AppState) -> Flow<Response, Error> {
if !state.ready {
return Flow::Exit(Error::ServiceUnavailable);
}
Flow::Continue(Response::ok())
}
This handler can be passed directly to [Server] without additional adapters.
Design Goals
- Make control flow explicit and visible in types
- Keep abstractions small and composable
- Avoid conflating errors with HTTP responses
- Stay close to standard library and Hyper concepts
This crate is not a batteries-included web framework. It is a foundation for building one, or for embedding HTTP handling into larger systems.