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()ExtensionsHeaderMapMethodPartsUriVersion(T1,)(T1, T2)(T1, ..., T16)-
Option<T>T: OptionalFromRequestParts<S> -
Result<T, T::Rejection>T: OptionalFromRequestParts<S> State<InnerState>MatchedPathNestedPathOriginalUriRawPathParamsRawQueryWebSocketUpgrade<DefaultOnFailedUpgrade>ConnectInfo<T>Extension<T>Path<T>Query<T>
-
FromRequestStringBytesBytesMutRequest<Body>(T1,)(T1, T2)(T1, ..., T16)-
Option<T>T: OptionalFromRequest<S> -
Result<T, T::Rejection>T: OptionalFromRequest<S> BodyMultipartRawForm-
TT: FromRequestParts<S> Form<T>Json<T>
HeaderMap, Path, Query, State, Json などよく見るものから、 Option や Result などちょっとクセのありそうなものまでありますね。 Request という直接的に受け取るものもあります。
ほかには FromRequestParts は同時に FromRequest でもあることも分かります。
Option のトレイト境界の OptionalFromRequest と OptionalFromRequestParts についても気になります。
FromRequest と FromRequestParts の違い
前回の impl_handler マクロのトレイト境界に出てきたとおり、 Handler の最後の引数は FromRequest<S, M> + Send というトレイト境界で、それ以外の引数は FromRequestParts<S> + Send というトレイト境界です。
FromRequest は request body を消費するので最後の 1 回だけ指定できます。
FromRequestParts は request body を消費しないので複数回指定できます。
FromRequest と FromRequestParts の違いは 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_request は Request<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 をとっています。
Parts は http::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 のためのトレイトである FromRequest と FromRequestParts の定義などを見ました。
次回はビルトインの Extractor を見てみます。
Discussion