Function aitch::middlewares::with_context[][src]

pub fn with_context<Ctx, Func, ReqBody, Resp>(
    ctx: Ctx,
    handler: Func
) -> impl Handler<ReqBody> where
    Ctx: Clone + Send + Sync + 'static,
    Func: Fn(Ctx, Request<ReqBody>, ResponseBuilder) -> Resp + Send + Sync + 'static,
    ReqBody: Body,
    Resp: Responder

A middleware which injects shared context into HTTP handlers.

The with_context function is a convenience that makes writing handlers with shared state as easy as possible. In many HTTP applications, handlers need access to shared context/state, such as database connection pools, or configuration information.

When using with_context, handler functions are written using the slightly different type signature, which accepts a context type as the first argument:

This example is not tested
Fn(ContextType, http::Request<impl Body>, ResponseBuilder) -> impl Responder

They are then wrapped with with_context(ctx, func), which returns a Handler which can be passed to middlewares/servers.

The only constraints on the context type, are that it implements Clone + Send + Sync. In many applications, this type will be an Arc, or something that uses Arc internally.

Example

extern crate aitch;
extern crate http;

use std::sync::Arc;

use aitch::servers::hyper::Server;
use aitch::{middlewares, Responder, ResponseBuilder, Result};
use http::Request;

struct Context {
    message: String,
    // In many applications, this context would also contain a database
    // connection pool, configuration data, and anything other state that
    // needs to be shared between handlers:
    // pool: DatabasePool,
    // config: Config,
}

fn handler(ctx: Arc<Context>, _req: Request<()>, mut resp: ResponseBuilder) -> impl Responder {
    resp.body(ctx.message.clone())
}

fn main() -> Result<()> {
    let ctx = Arc::new(Context {
        message: "Hello from a world with context!".to_owned(),
    });
    let handler = middlewares::with_context(ctx, handler);
    let wrapped = middlewares::with_stdout_logging(handler);

    let addr = "127.0.0.1:3000".parse()?;
    println!("Listening on http://{}", addr);
    Server::new(addr, wrapped)?.run()
}