Crate aitch[−][src]
aitch is a simple, lightweight toolkit for building HTTP servers in safe, stable Rust.
It builds upon the http
crate, and provides additional types for representing HTTP handlers,
bodies and middlewares. It provides both hyper
and tiny_http
backends for running
handlers, but aims to be agnostic of the HTTP server library.
It's inspired by the simplicity (and popularity) of Go's net/http
package, which builds
applications/middlewares as a series of nested Handler
s.
Defining Handler functions
Handlers are typically defined as functions with the signature:
Fn(http::Request<impl Body>, http::response::Builder) -> impl Responder
Both synchronous and asychronous handlers are defined using this same signature.
A Responder
is anything that implements IntoFuture<Item = http::Response<impl Body>>
,
whose Error
can be converted into a Box<Error>
. This will often be a Result
for
synchronous handlers, or something implementing Future
for asynchronous handlers.
For example, to define a simple sychronous handler as a function:
fn handler(_: http::Request<()>, mut resp: http::response::Builder) -> impl Responder { resp.body("Hello, world!".to_owned()) }
More complex Handlers using the Handler
trait
Handlers aren't limited to functions - any type that implements the Handler
trait can be used.
For an example of how to implement the Handler
trait for a more complex type, see the
provided SimpleRouter
, which routes HTTP requests to one of many handlers, based on the path
in the HTTP request.
Serving Requests
In order for a Handler
to serve requests, it needs to be passed to a server which can process
HTTP requests.
aitch comes with two server implementations:
aitch::servers::hyper::Server
, which useshyper
to receive and process requests. Ashyper
can take full advantage of asynchronous I/O, this server backend can support streaming request/response bodies.aitch::servers::tiny_http::Server
, which usestiny_http
to receive and process requests.tiny_http
uses a thread-pool to synchronously process each request, and the entire request body will be buffered before being past to the Handler - there is no support for streaming bodies.
The following example demonstrates passing a Handler function to
aitch::servers::hyper::Server
, which allows it to listen and respond to requests:
let addr = "127.0.0.1:3000".parse()?; aitch::servers::hyper::Server::new(addr, handler)?.run()
aitch aims to be agnostic of the server technology, and it should be possible to add support for other servers in third-party crates. The source code of the two provided server implementations should demonstrate how to do this.
Request/Response Bodies
The http::Request<B>
and http::Response<B>
types from the http
crate do not restrict
the type of the body used in requests and bodies.
The Body
trait is used by aitch to place some contraints on the body types used, so that handlers,
middlewares and servers can make assumptions about how to deserialize it from the raw HTTP
request, and how they should be serialized to the raw HTTP responses.
Writing Middlewares
In the context of aitch, a middleware is anything that takes one Handler
and returns another
(possibly modified) Handler
.
The simplest middleware, which does nothing but return the provided Handler
is written as:
fn noop_middleware<B: Body>(handler: impl Handler<B>) -> impl Handler<B> { handler }
Middlewares may mutate the http::response::Builder
before calling their wrapped handler, in
order to modify the response that will be returned:
fn with_served_by<B: Body>(handler: impl Handler<B>) -> impl Handler<B> { move |req, mut resp: http::response::Builder| { resp.header("X-Served-By", "aitch"); // Middleware authors should be aware that the wrapped handler is // under no obligation to use the provided `http::response::Builder`. handler.handle(req, resp) } }
aitch provides some sample middlewares, which provide more detailed examples of how third-party applications can create their own middleware.
Modules
handlers |
A collection of useful HTTP handlers. |
middlewares |
A collection of useful HTTP middlewares. |
servers |
Server back-ends which can be used to serve a handler. |
Structs
Json |
A wrapper, indicating a type should be automatically (de)serialized from/to a HTTP request/response body. |
Traits
Body |
A trait defining the types that can be used in HTTP requests and responses. |
Handler |
A trait indicating that the type can be used to handler to a HTTP request. |
Responder |
A |
Functions
box_handler |
Creates a |
Type Definitions
BodyStream |
A streaming body, which can be used in a HTTP request or response. |
BoxedHandler |
A |
BoxedResponse |
Represents a future returning a HTTP response, with all types erased. |
Error |
A generic error type for aitch handlers and middlewares. |
ResponseBuilder |
A type alias for |
Result |
A type alias to make working with |