2 unstable releases

0.2.0 Nov 18, 2019
0.1.0 Nov 5, 2019

#21 in #http-router

33 downloads per month

MIT license

23KB
334 lines

Pathmaker

Generalized routing for any HTTP library. Not too fancy.

Usage

To use this library, add the following to your Cargo.toml:

pathmaker = "0.1.0"

If you want to use it with a specific HTTP library, e.g. hyper, enable that feature:

hyper = "0.12"
pathmaker = { version = "0.1", features = ["hyper"] }

Then, in your code, construct a router:

extern crate hyper;
extern crate pathmaker;
extern crate failure;
extern crate futures;

use hyper::{Request, Response, Method, Body, Server};
use hyper::service::make_service_fn;
use hyper::header::CONTENT_LENGTH;
use pathmaker::hyper::Router;
use failure::Error;
use futures::prelude::*;

fn router() -> Router {
    let mut build = Router::build();
    build.get("/foo", |_, _| {
        let body = "Hello, world!";
        Box::new(futures::future::result(Response::builder()
            .header(CONTENT_LENGTH, body.len() as u64)
            .body(Body::from(body))
            .map_err(Error::from)
        ))
    });
    build.finish()
}

fn main() {
    let address = "0.0.0.0:8080".parse().unwrap();
    let server = Server::bind(&address)
        .serve(make_service_fn(|_| Ok::<_, hyper::Error>(router()))).map_err(|e| {
            eprintln!("error: {:?}", e);
        });
    // hyper::rt::run(server)
}

Query Parameters

Support for query parameters is allowed by using {} in the path:

// ...
fn router() -> Router {
    let mut build = Router::build();
    build.get("/foo", handler)
         .get("/hello/{}", hello_handler);
    build.finish()
}
// ...

Then, in the handler, you can access the first element of the second argument in order to get the result:

//...
fn hello_handler(_: Request<Body>, params: Vec<String>) -> Box<dyn Future<Item = Response<Body>, Error = Error> + Send> {
    let body = format!("Hello, {}!", params[0]);
    Box::new(futures::future::result(
        Response::builder()
            .header(CONTENT_LENGTH, body.len() as u64)
            .body(Body::from(body))
            .map_err(Error::from)
    ))
}
// ...

Query parameters can be filtered down by format:

  • {}, {:string} (the default): anything that isn't a / character is matched.
  • {:int}: a positive or negative number.
  • {:uint}: just a number, no sign allowed.
  • {:uuid}: a UUID, in 8-4-4-4-12 format.

More can be added if requested.

Route Evaluation

Routes are evaluated from top to bottom. The first route that matches is used.

Dependencies

~4–6.5MB
~117K SLoC