Rust 用のマイクロWebフレームワークを作ってみた
前回 は Hyper 用のルーティングライブラリを作ってみましたが,もう少し手を加えればちょっとしたマイクロフレームワークを作れるのではないと思い至ってしまったので勢いで作ってみました。
実用には程遠いレベルですが,ある程度フレームワークっぽい程度には実装できたので忘れないうちに内容をまとめておきます。
概要
プロジェクト名は「なんか日本神話っぽい名前のプロジェクト作りたい」という雑な考えで適当につけました。とくにスサノオノミコトへの思い入れがあるわけではないです…
コンセプトとしては,とにかくフレームワーク自体は小さくし,hyper
や futures
が扱っている領域は可能な限りそれらのクレート自体の機能をそのまま使えるようにというのを意識しています。
今のところ提供している機能は以下の通りです。
- ルーティング(
hyper-router
の実装をそのまま移植した) - ミドルウェアのサポート
使い方
※ 本記事内のサンプルコードは執筆時(2017-07-07)のバージョンに基づく
基本的なサンプル
単純な例を下に示します。まぁよくあるマイクロフレームワークの書き方と同じ感じですね…
extern crate susanoo; use susanoo::{Server, Context, AsyncResult}; use susanoo::contrib::futures::{future, Future}; use susanoo::contrib::hyper::{StatusCode, Response, Get}; fn hello(_ctx: Context) -> AsyncResult { let response = Response::new() .with_status(StatusCode::Ok) .with_body("<h1>Hello!</h1>"); future::ok(response).boxed() } fn main() { let server = Server::new() .with_route(Get, "/", hello); server.run("0.0.0.0:4000"); }
ミドルウェアの使用
nickel
と同様,ミドルウェアを用いて前段に処理をかませることが可能です。
ミドルウェア自体の実装は今後ちまちま進めていきたいと考えています。
// Authorization ヘッダの検証をするミドルウェア fn check_auth(mut ctx: Context) -> AsyncResult { /* omit */ } fn index(ctx: Context) -> AsyncResult { let user = ctx.map.get::<User>().unwrap(); future::ok( Response::new() .with_status(StatusCode::Ok) .with_body(format!("<h1>Welcome, {}!</h1>", user.username)) .into(), ).boxed() } fn main() { let server = Server::new() .with_middleware(check_auth) .with_route(Get, "/", index); server.run("0.0.0.0:4000") }
その他細かい仕様やサンプルなどはソースコードを参照してください(正直具体的な仕様もまだ確定していないのですが…)
作ってみた感想など
- フレームワークを作るの自体はすごく簡単だった
- 主要な機能は
hyper
/futures
/tokio
が提供しているものを使えば良い - とにかくRustはエコシステムが充実してきており良い
- 主要な機能は
- 所有権回り,借用チェッカとの闘いが辛い
- いまだに慣れない…
- 特に並行処理周りの知識が足りないせいか,雰囲気で型制約を書いてしまっている箇所が多い
おわりに
正直主要なフレームワーク(iron
/ nickel
/ rocket
)が futures
に対応するまでの話な気もしますが,フレームワークの自作自体は結構面白かったので今後もチマチマとメンテナンスしていけたらなぁと