nickel.rs

web application framework for rust

Your first nickel app

#[macro_use] extern crate nickel;

use nickel::Nickel;

fn main() {
    let mut server = Nickel::new();

    server.utilize(router! {
        get "**" => |_req, _res| {
            "Hello world!"
        }
    });

    server.listen("127.0.0.1:6767").unwrap();
}

Flexible routing

Routes can be as simple as /foo, use parameters, wildcards or even double wildcards.

#[macro_use] extern crate nickel;

use nickel::{Nickel, HttpRouter};

fn main() {
    let mut server = Nickel::new();

    server.get("/bar", middleware!("This is the /bar handler"));
    server.get("/user/:userid", middleware! { |request|
        format!("This is user: {:?}", request.param("userid"))
    });
    server.get("/a/*/d", middleware!("matches /a/b/d but not /a/b/c/d"));
    server.get("/a/**/d", middleware!("This matches /a/b/d and also /a/b/c/d"));

    server.listen("127.0.0.1:6767").unwrap();
}

Middleware

Middleware are the extensibility points of nickel. Batteries included! A bunch of existing Middleware comes right with nickel.

#[macro_use] extern crate nickel;

use nickel::{Nickel, StaticFilesHandler};

fn main() {
    let mut server = Nickel::new();

    server.utilize(StaticFilesHandler::new("examples/assets/"));

    server.listen("127.0.0.1:6767").unwrap();
}

JSON handling

nickel makes it easy to map JSON data right onto your struct.

This example requires adding the rustc-serialize dependency to your Cargo.toml

extern crate rustc_serialize;
#[macro_use] extern crate nickel;

use nickel::{Nickel, HttpRouter, JsonBody};

#[derive(RustcDecodable, RustcEncodable)]
struct Person {
    firstname: String,
    lastname:  String,
}

fn main() {
    let mut server = Nickel::new();

    server.post("/a/post/request", middleware! { |request, response|
        let person = request.json_as::<Person>().unwrap();
        format!("Hello {} {}", person.firstname, person.lastname)
    });

    server.listen("127.0.0.1:6767").unwrap();
}

Custom error handler

By default nickel catches all errors with its default ErrorHandler and tries to take reasonable actions. In cases where one wants to provide an own ErrorHandler (e.g. for custom 404 pages), it's trivial to write one.

#[macro_use] extern crate nickel;

use std::io::Write;
use nickel::status::StatusCode::NotFound;
use nickel::{Nickel, NickelError, Action, Continue, Halt, Request};

fn main() {
    let mut server = Nickel::new();

    //this is how to overwrite the default error handler to handle 404 cases with a custom view
    fn custom_404<'a>(err: &mut NickelError, _req: &mut Request) -> Action {
        if let Some(ref mut res) = err.stream {
            if res.status() == NotFound {
                let _ = res.write_all(b"<h1>Call the police!</h1>");
                return Halt(())
            }
        }

        Continue(())
    }


    // issue #20178
    let custom_handler: fn(&mut NickelError, &mut Request) -> Action = custom_404;

    server.handle_error(custom_handler);

    server.listen("127.0.0.1:6767").unwrap();

}

Easy Templating

Nickel supports defining templates with mustache.rs. All you need is to create the template...

<html>
    <body>
        <h1>
            Hello {{ name }}!
        </h1>
    </body>
</html>

...and pass it to response.render(template, data).

#[macro_use] extern crate nickel;

use std::collections::HashMap;
use nickel::{Nickel, HttpRouter};

fn main() {
    let mut server = Nickel::new();

    server.get("/", middleware! { |_, response|
        let mut data = HashMap::new();
        data.insert("name", "user");
        return response.render("examples/assets/template.tpl", &data);
    });

    server.listen("127.0.0.1:6767").unwrap();
}

About

nickel is brought to you by the people of thoughtram and friends. It's MIT licensed. We welcome your contribution.