メインコンテンツまでスキップ

型安全な情報抽出

Actix Webは、型安全なリクエスト情報アクセスのための機能として、エクストラクタ(すなわちimpl FromRequest)を提供します。Actix Web 標準エクストラクタの実装が多く用意されています。(implementorsを参照)

エクストラクタは、ハンドラ関数の引数としてアクセスすることができます。Actix Web は、ハンドラ関数ごとに最大12個のエクストラクタをサポートします。引数の位置は順不同です。


パス(Path)

Pathは、リクエストのパスから抽出された情報を提供します。抽出可能なパスの部分は"動的セグメント(dynamic segments)"と呼ばれ、波括弧(curly braces)でマークされています。パスから任意の動的セグメントをデシリアライズすることができます。

たとえば、/users/{user_id}/{friend} というパスで登録したリソースに対しては、 user_idfriend というふたつのセグメントをデシリアライズします。これらのセグメントは、宣言された順にタプルとして取り出すことができます (例: Path<(u32, String)>)。


また、動的セグメント名とフィールド名をマッチングさせることで、serde から Deserialize トレイトを実装した型へのパス情報を抽出することも可能です。以下は、タプル型の代わりに serde を使用した、同等の例です。


型安全ではないものの代替として、ハンドラ内でパス引数の名前で リクエストを問い合わせることもできます。(match_info docsを参照。)


クエリ(Query)

Query<T>型は、リクエストのクエリパラメータを抽出する機能を提供します。その下にはserde_urlencodedクレートが使用されています。


JSON

Json<T>は、リクエストボディを構造体にデシリアライズすることができます。リクエストのボディから型付けされた情報を取り出すには、型 Tserde::Deserialize を実装している必要があります。


エクストラクタのなかには、 抽出処理を設定する方法を提供しているものがあります。エクストラクタを設定するには、リソースの .app_data() メソッドにその設定オブジェクトを渡します。Json エクストラクタの場合、JsonConfig が返されます。JSONペイロードの最大サイズと、カスタムエラーハンドラ関数を設定することができます。

次の例では、ペイロードのサイズを4kbに制限し、カスタムエラーハンドラを使用しています。


URLエンコードされたフォーム

URLエンコードされたフォームの body 部分は、Json<T> のような構造体に抽出することができます。この型は、serde::Deserialize を実装する必要があります。

FormConfigでエクストラクタ処理を設定することができます。


その他

Actix Webは他にも多くのエクストラクタを提供していますが、ここでは重要なものをいくつか紹介します。

  • Data - アプリケーションのステートにアクセスする

  • HttpRequest - HttpRequestはそれ自体がエクストラクタであり、リクエストの他の部分にアクセスする必要がある場合に備えています。

  • String - リクエストのペイロードを String に変換することができます。サンプルコード

  • Bytes - リクエストのペイロードをBytesに変換することができます。サンプルコード

  • Payload - 主に他の抽出器を構築するための低レベルのペイロード抽出器です。サンプルコード

アプリのステートエクストラクタ

アプリケーションのステートは、ハンドラから web::Data エクストラクタでアクセスできます。しかし、ステートは読み取り専用の参照としてアクセスできます。もしステートにミュータブルなアクセスが必要な場合は、それを実装する必要があります。

以下は、処理されたリクエストの数を保存するハンドラの例です。


このハンドラは動作しますが、data.count は各ワーカスレッドで処理されたリクエストの数しか数えません。すべてのスレッドにまたがる総リクエスト数を数えるには、shared な Arcatomicsを使う必要があります。


注意: すべてのスレッドでステート全体を共有したい場合は、Sharedな可変ステートで説明したように、web::Dataapp_data を使用します。

MutexRwLock などの同期を実現する為の組込をアプリのステート内で使用する場合は、注意が必要です。Actix Webはリクエストを非同期で処理します。ハンドラ内のcritical sectionが大きすぎたり、.await ポイントが含まれていたりすると問題です。これが気になる場合は、Tokio's advice on using blocking Mutex in async codeも読むことをお勧めします。