💬

axum crate の Extractor

に公開

前回は axum crate の Handler の実装を追いかけてみました

今回は axum crate の Extractor を見ていきます。

今回も axum crate のバージョンは 0.8.6 です。

axum crate の Extractor とは

axum crate の Extractor は FromRequest または FromRequestParts を実装した型です。 Handler の引数として 0 個以上の Extractor を指定できます。

リクエストから値を抽出 (extract) するから Extractor ということでしょう。

https://docs.rs/axum/0.8.6/axum/index.html#extractors
https://docs.rs/axum/0.8.6/axum/extract/index.html

ビルトインの Extractor

ビルトインの Extractor を調べるには FromRequestParts trait と FromRequest trait のドキュメントからたどると良さそうです。

https://docs.rs/axum/0.8.6/axum/extract/trait.FromRequestParts.html
https://docs.rs/axum/0.8.6/axum/extract/trait.FromRequest.html

次のような型への実装が提供されていることが分かります。

  • FromRequestParts
    • ()
    • Extensions
    • HeaderMap
    • Method
    • Parts
    • Uri
    • Version
    • (T1,)
    • (T1, T2)
    • (T1, ..., T16)
    • Option<T> T: OptionalFromRequestParts<S>
    • Result<T, T::Rejection> T: OptionalFromRequestParts<S>
    • State<InnerState>
    • MatchedPath
    • NestedPath
    • OriginalUri
    • RawPathParams
    • RawQuery
    • WebSocketUpgrade<DefaultOnFailedUpgrade>
    • ConnectInfo<T>
    • Extension<T>
    • Path<T>
    • Query<T>
  • FromRequest
    • String
    • Bytes
    • BytesMut
    • Request<Body>
    • (T1,)
    • (T1, T2)
    • (T1, ..., T16)
    • Option<T> T: OptionalFromRequest<S>
    • Result<T, T::Rejection> T: OptionalFromRequest<S>
    • Body
    • Multipart
    • RawForm
    • T T: FromRequestParts<S>
    • Form<T>
    • Json<T>

HeaderMap, Path, Query, State, Json などよく見るものから、 OptionResult などちょっとクセのありそうなものまでありますね。 Request という直接的に受け取るものもあります。

ほかには FromRequestParts は同時に FromRequest でもあることも分かります。

Option のトレイト境界の OptionalFromRequestOptionalFromRequestParts についても気になります。

FromRequest と FromRequestParts の違い

前回impl_handler マクロのトレイト境界に出てきたとおり、 Handler の最後の引数は FromRequest<S, M> + Send というトレイト境界で、それ以外の引数は FromRequestParts<S> + Send というトレイト境界です。

FromRequest は request body を消費するので最後の 1 回だけ指定できます。

FromRequestParts は request body を消費しないので複数回指定できます。

FromRequestFromRequestParts の違いは request body を消費するかどうか、ひとつの Handler に何回指定できるか、どこで指定できるかが基本ということですね。

さきほどの impl FromRequest の一覧からも request body をどう解釈するかというものなのが読み取れそうですね。

FromRequest の定義

FromRequest の定義を見ます。

https://docs.rs/axum/0.8.6/axum/extract/trait.FromRequest.html
https://docs.rs/axum-core/0.5.5/src/axum_core/extract/mod.rs.html#79

pub trait FromRequest<S, M = ViaRequest>: Sized {
    type Rejection: IntoResponse;

    // Required method
    fn from_request(
        req: Request<Body>,
        state: &S,
    ) -> impl Future<Output = Result<Self, Self::Rejection>> + Send;
}

from_requestRequest<Body> をとっています。

request (body) を消費していますね。

FromRequestParts の定義

FromRequestParts の定義を見ます。

https://docs.rs/axum/0.8.6/axum/extract/trait.FromRequestParts.html
https://docs.rs/axum-core/0.5.5/src/axum_core/extract/mod.rs.html#53

pub trait FromRequestParts<S>: Sized {
    type Rejection: IntoResponse;

    // Required method
    fn from_request_parts(
        parts: &mut Parts,
        state: &S,
    ) -> impl Future<Output = Result<Self, Self::Rejection>> + Send;
}

from_request_parts&mut Parts をとっています。

Partshttp::request::Parts です。

https://docs.rs/http/1.3.1/http/request/struct.Parts.html

pub struct Parts {
    pub method: Method,
    pub uri: Uri,
    pub version: Version,
    pub headers: HeaderMap<HeaderValue>,
    pub extensions: Extensions,
    /* private fields */
}

request body は含まれていません。 &mut Parts のとおり、参照を渡されています。

おわりに

今回は Extractor のためのトレイトである FromRequestFromRequestParts の定義などを見ました。

次回はビルトインの Extractor を見てみます。

GitHubで編集を提案
ドクターメイト

Discussion