7 releases

0.3.8 Apr 21, 2023
0.3.7 Mar 31, 2023
0.3.5 Jan 23, 2023
0.3.3 Nov 24, 2022
0.2.0 Mar 6, 2022

#1377 in HTTP server

MIT license

175KB
2K SLoC

Under

Version docs.rs License CI

A very simple HTTP server framework. This serves as a small layer between your application code and Hyper.

Right now, this layer is very bare-bones - however, the intent is to add on to this whenever patterns with the code become obvious. If you encounter any, feel free to create an issue.

Setting Up

The simplest way to set up a server is by using under::Router:

let mut http = under::http();
http.at("/").get(under::endpoints::simple(under::Response::empty_204));
http.listen("localhost:8080").await.unwrap();

This will cause the application to run an HTTP server on port 8080 locally; running GET / would return 204 No Content.

The router accepts all kinds of verbs:

http.at("/users")
    .get(users::index)
    .post(users::create)
    .at("/{id}")
        .get(users::show)
        .put(users::update)
        .delete(users::delete);

Note the hirearchal structure of the at calls - if the latter at is called underneath an already existing at, then the paths are joined. The above example is equiavlent to:

http.at("/users")
    .get(users::index)
    .post(users::create);
http.at("/users/{id}")
    .get(users::show)
    .put(users::update)
    .delete(users::delete);

For verbs that are not included by default, you may use the method function to declare one:

http.at("/users/{id}")
    .method(hyper::Method::from_bytes(b"SOMETHING").unwrap(), users::something);

Or, if you want to capture all methods, you can use the all function to do so:

http.at("/users/{id}").all(users::all);

Endpoints

When declaring a path, it must route to an endpoint - the argument passed into the verb function, e.g. get(users::show). The value passed must implement under::Endpoint. under::Endpoint is implemented for fn(under::Request) -> impl Future<Output = Result<under::Response, anyhow::Error> + Send + Sync + 'static; so, declaring an endpoint can be as simple as:

async fn index(request: under::Request) -> Result<under::Response, anyhow::Error> {
    todo!()
}

and used as above. This library also comes with a few built-in endpoints in under::endpoints.

Dependencies

~12–23MB
~329K SLoC