現時点で 0.8.1 まで出てしまっていますので、まとめて触ってみます。
変更の概要はこちらのリリースノートに詳しくまとまっています。0.8.0 でかなり大掛かりなモジュールの構造に対する変更が入っており、もともとドッグフーディングのために使用していたコードベースを 0.7.0→0.8.0 バージョンに上げた際に、いくつかコンパイルエラーになってしまったコードがありました。
まだまだ開発途上なので致し方ないのですが、tide はこういったバージョンアップによって既存のコードベースがコンパイルエラーしてしまうことが多いです。本番環境で利用する際には、こういった点にまだ注意が必要だと思います。
具体的に修正の入ったモジュールは、
- tide::server サブモジュールの削除
- tide::middleware サブモジュールの削除
でした。この中に Cookie などが含まれていましたので、使用していた方は変更が必要だった可能性があります。
前回の記事は下記です。
リリースノートで気になったもの
- エンドポイントで
?
の使用をできるようになった - Server-Sent Events をできるようになった
- 静的ファイルのサービングをできるようになった
エンドポイントで ?
の使用をできるようになった
リリースノート以上の解説の必要はないと思うので割愛しますが、エンドポイントの実装時に ?
を用いてエラーハンドリングをできるようになりました。
use async_std::{fs, io}; use tide::{Response, StatusCode}; #[async_std::main] async fn main() -> io::Result<()> { let mut app = tide::new(); app.at("/").get(|_| async move { let mut res = Response::new(StatusCode::Ok); res.set_body(fs::read("my_file").await?); Ok(res) }); app.listen("localhost:8080").await?; Ok(()) }
リリースノートのコードをそのまま引っ張ってきてしまいましたが、このように書けるようになりました。?
の結果が Error
だった場合は、自動的に 500 Internal Server Error が割り当てられます。
Server-Sent Events をできるようになった
Server-Sent Events というのは、サーバーからプッシュ通信を行えるようにする機能です。W3C によって提案されている内容です。HTTP/1.1 のチャンク形式を元にした機能で、チャンクの少しずつ送信するという特徴を利用して、サーバーから任意のタイミングでクライアントにイベントを通知できます。WebSocket と似ていますが、WebSocket とは HTTP を利用するという点で異なります。
送られた内容を、JavaScript の EventSource API にて取得します。詳しい仕様。
今回は curl で確認できそうなので、curl で確認してみます。
コードはリリースノートのそのままなのですが…
use tide::sse; #[async_std::main] async fn main() -> Result<(), std::io::Error> { let mut app = tide::new(); app.at("/sse").get(sse::endpoint(|_req, sender| async move { sender.send("fruit", "banana", None).await; sender.send("fruit", "apple", None).await; Ok(()) })); println!("Server starts"); app.listen("localhost:8080").await }
こういった感じで実装し、サーバーを起動したことを確認します。
tide-dog-fooding is 📦 v0.1.0 via 🦀 v1.43.0 took 3m25s ❯ cargo run Compiling tide-dog-fooding v0.1.0 (~/github/yuk1ty/tide-dog-fooding) Finished dev [unoptimized + debuginfo] target(s) in 2.86s Running `target/debug/tide-dog-fooding` Server starts
curl を投げてみた結果です。Content-Type が text/event-stream
になっていて、ボディも Server-sent Events の形式に沿っていることがわかりました!
❯ curl localhost:8080/sse -i HTTP/1.1 200 OK transfer-encoding: chunked date: Sat, 16 May 2020 06:46:34 GMT cache-control: no-cache content-type: text/event-stream event:fruit data:banana event:fruit data:apple
内部の実装的には、async-sse
というクレートをそのまま利用しているようです。async-std 関係のエコシステムがかなり充実してきていますね。
静的ファイルのサービングをできるようになった
掲題の通りですが、静的ファイルを扱えるようになりました。
この修正に伴って、Route#middleware
関数に型引数が追加になり、その型引数 M
に Debug を derive しているという条件が追加されました。なので、従来使用していた Middleware の独自実装のすべての構造体に対して、Debug
トレイトを継承させる必要が出てきたため注意が必要です。
余談ですが、0.8.0 時点ではディレクトリトラバーサルが可能な状態のようでしたが、0.8.1 でディレクトリトラバーサル対策を行った PR がマージされています。なので、静的ファイルのサービングを行いたい場合は 0.8.0 を利用しないほうがよさそうです。
感想
PR を1つ1つ読むのがおもしろいです。HTTP サーバーフレームワークをフルスクラッチした経験はないので、どのように開発が進んでいっているかが追えて楽しいです。引き続き tide の更新情報は追っていきたいです。
ただ、バージョンを上げるたびにわりと毎回破壊的な変更が入っていて、前バージョンまで使っていたコードが動かなくなる、またはコンパイルエラーの潰しこみが必要になります。なので、tide はまだちょっと本番では試せないかなという印象です。