Rust
Rocket
Request
Rocketとは
Nightly Rustでしか動作しない
rustup default nightly
開発用ツールもインストールしとく
rustup component add rls rust-src rust-analysis
Cargo.toml にrocketを書く
解説
ロケットに積荷を搭載して発射するイメージ
httpリクエストに対する処理の流れ
mod 機能を使って、ハンドラーをモジュール化するときは
module名まで含めないとエラーになる。
route!マクロがコード生成できないため
全部訳すとだるいので要点だけ
同じようなrouteがあった場合、ランクが高い方を優先してアクセスする。
routeアトリビュートに、rank = で明示できる
-6 ~ -1まで
変数を含んでいなかったり、? から始まるクエリパラメータを
含んでいると高くなるというルール。
静的ファイルのホスティングは、以下のコードでできる。
/static/ フォルダにあるファイルを /public/path
でアクセスできるようにする。
あってもなくてもいいパスのときは、ハンドラで
Option型で受け取る。
?..&…&…のような、複数クエリを取って
#[derive(FromForm)] を実装した構造体に割り当てられる
url例
/item?id=100&name=sandal&account=400
リクエストに含まれる情報に基づいて、誤ってハンドラを
呼び出さないようにする。
もっと詳しく言えば、リクエストガードは任意の検証ポリシーである
FromRequestトレイトとして実装する。
リクエストガードはハンドラへの入力として扱われる。
Rocketはハンドラを呼び出す前に、リクエストガードの実装を自動的に呼び出す。
すべてのガードを通過したとき、ハンドラにリクエストをディスパッチする。
下記のハンドラでは、A, B, Cの3つのリクエストガードを使う(そんな名前のないけど)
いくつかのFromRequest実装は、Rocketに組み込みで用意されている
主に、httpリクエストのヘッダに含まれる情報を抽出するのに使える
実装方法はrocketのapiドキュメントの rocket::request::FromRequest トレイト
の実装例を見る
User と AdminUser の2つのリクエストガードを使って、
管理ユーザーしか見られないページを実装する
(User と AdminUser はカスタムリクエストガード)
routeアトリビュートは、リクエストが送ってくるデータフォーマットを定義できる
payload を設定できる put, post, delete, patchメソッドでの
Jsonリクエストの場合は format="application/json" となる
dataは <user> パラメータで受け取っているので、引数では user: Json<T> 型で
受け取れる
また、 "application/json" の部分は、 "json" と省略もできる
利用できる略称のリストは、 (rocket::http::ConentType::parse_flexible())[https://api.rocket.rs/v0.4/rocket/http/struct.ContentType.html#method.parse_flexible]
の説明を見る
payloadがないタイプのメソッドでも、HttpレスポンスのAcceptの値がjsonに
なってるかどうかをチェックする。
ハンドラの戻り値がjsonである必要があるならformatを記述するべき
routeアトリビュートで data="<変数名>" にして ハンドラの同名引数で受け取る
FromDataトレイトを実装する型で受け取れる
httpのformで入力したキーバリューを含んだpostの場合、
#[derive(FromForm)]を実装した構造体に、formの値を割り当てられる
Form<T> のTに、構造体の型を入れる
formの値は、Task構造体にパースされ
ハンドラの中で使えるようになる。
パースできなかったり不正な値のときは
400 - Bad Request or 422 - Unprocessable Entity
Option型やResult型でも受け取れる
lenient = ゆるい、寛大な
Form<T>型で受け取ると、formのキーと値のペアが割り当てる構造体に
過不足ない状態でないとエラーになる
LenientForm<T>で受け取ると、フィールドが多すぎる場合は問題なく
必要な部分だけパースするといったことを行ってくれる
例.
structのフィールドについて、Rustのプログラム上で使う名前と
Form<T>などで割り当てられる名前が一致しない場合、
Form割当のとき使う名前をアトリビュートで設定できる。
もしもInvalidなら、ハンドラが呼ばれない
FromFormValueトレイトは、enum型にも実装できる
その際は#[derive(FromFormValue)]でいける
Valiantに含まれる値以外ならinvalid
構造体に、#[derive(Deserialize)] を実装すると
httpリクエストのbodyのjson文字列から、構造体に直せる
Json type は rocket_contriveに含まれる
Deserializeトレイとは Serde というクレートに依存している。
githubのrocket getstarted json example をみる
streaming (流れるように送られてくる)データを扱いたい場合
Rocketが用意している Data 型を使う
format は "plane"
DoS攻撃を防止するためにも、受信するデータ量は制限する必要がある。
take()メソッドを使うのが簡単
ルーティングは失敗する可能性をはらんでいる