にっき

技術的な話題はないです

自作 Rust WAF の供養

ここ一、二年の間に何個か Rust の Web フレームワークを作ってきたので、それらの総括(および供養)をしておきます。

Susanoo

github.com

はじめに作成した Hyper 0.11 ベースの Web フレームワークです。 作り始めた当初は futures ベースの非同期フレームワークがほとんど無いような状況で(ちょうど Shio や Gotham が同じ時期に台頭してきた記憶あり)、他言語の WAF の情報を眺めながら試行錯誤で開発を続けていました。 結果的に実用段階まで到達するどころかまともなコンセプトすら定まる事なく消滅したプロジェクトですが、このときに試行錯誤した経験が後のフレームワークを実装する上での経験となったので無意味ではなかったでしょう(そのはずですが…)。

他のフレームワークが成熟(あるいは開発が続かず頓挫)してきたこともあり、現在では開発を完全に停止した上で後述する Tsukuyomi に完全に移行しました。

Finchers

github.com

Susanoo のルーティング周りの実装するに当たり ScalaFinch を見つけ、それを Rust で再現できないかと試してみたのがきっかけで開発を開始したプロジェクトです。要は HTTP に特化したパーサコンビネータのようなもので、予め用意されているコンポーネントを組み合わせていくことで Web サービスを構築していきます。このコンセプトに基づく Web フレームワークはまだそこまで数はないので、地道に活動を続けていければ今後も生き残らせることが出来るかもしれません(もちろん個人のプロジェクトなので限度はありますが…)。

use finchers::prelude::*;

let get_post = finchers::path!(@get / "posts" / i32 /)
    .and_then(|id: i32| {
        crate::api::get_posts(id).from_err().map(Json)
    });

let create_post = finchers::path!(@post / "posts" /)
    .and(endpoints::body::json())
    .and_then(|new_post: NewPost| {
        crate::api::create_post(new_post).from_err().map(Json)
    });

let endpoint = get_post.or(create_post);

ちまちまと変更を加えつつ割と放置していたのですが、今年に入って同様のコンセプトである warp が台頭してきたことを受けて開発を再開しました。

Tsukuyomi

github.com

事実上の Susanoo version 2 です。 Susanoo を改修することに嫌気が差していたので、 Hyper のバージョンを 0.12 に更新するついでにゼロから実装し直したものになります。

今の所、著名なフレームワーク(Actix-web, Gotham および Tower-web)と比較して優位になるセールスポイントがないのですが、暇があれば開発を続けたいとは思っています。思ってはいますが…

おわりに

節操なくプロジェクトを立ち上げすぎたと反省している。