#server #http #web #framework

sailboat

Simplicity focused http framework providing ergonomic and fast bindings

2 unstable releases

0.1.0+1 Mar 16, 2023

#288 in WebSocket

Download history 4/week @ 2023-11-13 4/week @ 2023-11-20 5/week @ 2023-11-27 4/week @ 2023-12-04 2/week @ 2023-12-11 4/week @ 2023-12-25 2/week @ 2024-01-01 1/week @ 2024-01-08 4/week @ 2024-01-29 1/week @ 2024-02-05 11/week @ 2024-02-12 46/week @ 2024-02-19

62 downloads per month

MIT/Apache

27KB
498 lines

Sailboat

The problem

The rust http server framework genre seems to be filled with a large overuse of macros to produce framework structures that are essentially a sub-language of rust.

The solution

Sailboat is focused on simplicity while still maintaining speed. This library avoids complex, unclear, or otherwise unnecessary macros preferring instead to write (at times) more verbose yet clear; clean code.

Checklist

Order of tasks not necessarily in order of completion

  • Basic routing

  • URL parameters

  • Multithreading responses

  • Application wide resources/context

  • Websockets

  • Move to async

  • Ssl/Https

  • Optimizations

  • Custom Http implementation

Example

Run examples using cargo run --example example_name

A basic hello world program using sailboat:

use sailboat::{
    application::Application,
    executor::DefaultExecutor,
    request::Request,
    response::Response,
    service::{Command, Point},
    StatusCode,
};

type Data = ();

async fn hello_world<'a>(_req: &mut Request<'a>, _ctx: &Data) -> Command<Data> {
    // Responding with `None` will act as a middleware System
    // Responding with `Some` will respond to the request object and move on to the next request
    // All systems registered after receiving a `Some` will not be run

    Command::Respond(Response::empty(StatusCode(200)))
}

fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let root = Point::root().fold(|s| {
        // `localhost/hello_world`
        s.push_child(Point::with_system(
            "hello_world",
            hello_world,
        ))
    });

    // The application will automatically respond to all unrecognized urls with a `StatusCode(404)` not found
    // In this case, the only recognized url is `localhost/hello_world`
    let app = Application::<DefaultExecutor>::new("0.0.0.0:8080", root, ())?;

    // Initiate main application loop
    let _ = app.run();

    Ok(())
}

Performance

On my personal computer using wrk -t 4 -c 4 A basic hello_world example revealed the following

  • sailboat: ~240k req/sec
  • actix: ~280k req/sec
  • tiny_http: ~280k req/sec
  • rouille: ~80k req/sec

Documentation

This crate aims to be 100% fully documented.

Licensing

See LICENSE-MIT

Dependencies

~2.4–3.5MB
~55K SLoC