[Rust] expressライクなWebフレームワーク – nickel.rs

2022.05.02

Introduction

nickel.rsはRust用Webフレームワークです。
このフレームワークはnodeで人気のexpressにインスパイアされており、
軽量でシンプルに扱うことができます。

Environment

  • MacBook Pro (13-inch, M1, 2020)
  • OS : MacOS 11.3.1
  • rust : 1.60.0

Try nickel.rs

ではnickelを試してみましょう。まずはcargoでアプリの作成。

% cargo new nickel-demo --bin && cd nickel-demo
     Created binary (application) `nickel-demo` package

Cargo.tomlのdependenciesにライブラリを追加。

[dependencies]
nickel = "0.11.0"

main.rsを以下のように修正。
Nickel::newでサーバオブジェクトを作成してハンドラを登録しています。
utilize関数は、リクエスト前に他のミドルウェアハンドラの中から
起動されるハンドラを登録します。
expressと同じように、middlewareは積み重ねることができ、登録した順番に呼び出されます。

#[macro_use] extern crate nickel;

use nickel::{Nickel,HttpRouter};

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

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

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

cargo runで起動し、
http://127.0.0.1:6767にアクセスするとHello Worldが表示されます。

% cargo run 
% curl http://127.0.0.1:6767
Hello world!

Routing

↓のようにrouting登録ができます。

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

    server.get("/foo", middleware!("This is the /foo handler"));
    server.get("/bar", middleware!("This is the /bar handler"));

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

router!マクロでrouting登録も可能です。  

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

    server.utilize(router! {
        get "/foo" => |_req, _res| {
            "This is the /foo handler"
        }
        get "/bar" => |_req, _res| {
            "This is the /bar handler"
        }
    });

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

Middleware

expressといえばmiddleware。
nickelでもmiddlewareをスタックして処理を実行できます。
↓ではmiddleware!マクロですべてのリクエストに対して
ログ出力処理を追加しています。

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

    server.utilize(middleware! { |req|
        println!("logging request: {:?}", req.origin.uri);
    });

    server.utilize(router! {
        get "/foo" => |_req, _res| {
            "This is the /foo handler"
        }
        get "/bar" => |_req, _res| {
            "This is the /bar handler"
        }
    });

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

Template

nickelは標準でmustache.rsテンプレートが使用可能です。
nickel-demo/assetsディレクトリを作成してtemplate.tplを下記のように作成。

<html>
    <body>
        <h1>
            Counter : {{ counter }}!
        </h1>
    </body>
</html>

main.rsでカウンターを作成し、テンプレートに渡します。

#[macro_use] extern crate nickel;

use nickel::{Nickel,HttpRouter};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::collections::HashMap;

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

    let visits = AtomicUsize::new(0);

    server.utilize(middleware! { |req|
        println!("logging request: {:?}", req.origin.uri);
    });

   server.get("/buzz", middleware! { |_, response|
       let mut data = HashMap::new();
       let count = visits.fetch_add(1, Ordering::Relaxed);
       data.insert("counter", count);
       return response.render("assets/template.tpl", &data);
   });

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

http://127.0.0.1:6767/buzzにアクセスすると、
template.tpl内容が表示されます。

Summary

RustのWebフレームワーク、nickelを試してみました。
expressに慣れた人なら理解しやすそうです。

References