エクストラクター
リクエストを解析します
「エクストラクター」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。
extractor とは
extractor は、リクエストから必要な一部を取り出してくれるハンドラーのパラメーターです。Axum はパラメーターの型を調べて、値を設定します。
- リクエストを手動で解析する必要がない
- 型を中心に構成でき、組み合わせも可能である
Path extractor
Path は動的な URL セグメントを取得します。内部の型によって、セグメントの解析方法が決まります。
use axum::extract::Path;
async fn user(Path(id): Path<u32>) -> String {
format!("user {}", id)
}複数のパスパラメーター
タプルを抽出すると、複数のセグメントを取得できます。順序はパスのパターンと一致します。
use axum::extract::Path;
async fn item(Path((cat, id)): Path<(String, u32)>) -> String {
format!("{} / {}", cat, id)
}Query extractor
Query は serde を使って URL のクエリ文字列を構造体にデシリアライズします。フィルターやページネーションに便利です。
use axum::extract::Query;
use serde::Deserialize;
#[derive(Deserialize)]
struct Page { page: u32 }
async fn list(Query(p): Query<Page>) -> String {
format!("page {}", p.page)
}JSON ボディ extractor
Json はリクエストボディを構造体にデシリアライズします。構造体には Deserialize を derive する必要があります。
use axum::Json;
use serde::Deserialize;
#[derive(Deserialize)]
struct NewUser { name: String }
async fn create(Json(u): Json<NewUser>) -> String {
format!("created {}", u.name)
}Headers extractor
HeaderMap extractor または型付きヘッダー extractor を使ってヘッダーにアクセスします。認証トークンに便利です。
use axum::http::HeaderMap;
async fn show(headers: HeaderMap) -> String {
match headers.get("x-api-key") {
Some(v) => format!("key: {:?}", v),
None => "no key".to_string(),
}
}extractor の順序が重要
Json のようにボディを消費する extractor は、パラメーターリストの最後に置く必要があります。ボディは 1 回しか読み取れないためです。
use axum::{Json, extract::Path};
use serde::Deserialize;
#[derive(Deserialize)]
struct Body { value: i32 }
async fn h(Path(id): Path<u32>, Json(b): Json<Body>) -> String {
format!("{} {}", id, b.value)
}通常の Rust で抽出をモデル化する
抽出とは、リクエストから型付きデータを解析することにすぎません。ここでは、クエリのような文字列を数値にデシリアライズします。
fn parse_query(q: &str) -> Option<u32> {
q.strip_prefix("page=")?.parse().ok()
}
fn main() {
println!("{:?}", parse_query("page=3"));
println!("{:?}", parse_query("bad"));
}オプションの抽出
extractor を Option で包むと、失敗しても処理を継続できます。値がない場合や無効な場合は、エラーレスポンスではなく None になります。
use axum::extract::Query;
use serde::Deserialize;
#[derive(Deserialize)]
struct Filter { q: String }
async fn search(filter: Option<Query<Filter>>) -> String {
match filter {
Some(Query(f)) => f.q,
None => "no filter".to_string(),
}
}リジェクション
extractor が失敗するとリジェクションを返し、それが HTTP エラーレスポンスになります。たとえば、無効な JSON には自動的に 422 が返されます。
use axum::extract::rejection::JsonRejection;
use axum::Json;
async fn create(body: Result<Json<i32>, JsonRejection>) -> String {
match body {
Ok(Json(n)) => format!("ok {}", n),
Err(_) => "bad body".to_string(),
}
}extractor の組み合わせ
ハンドラーでは複数の extractor を同時に使えます。Axum がリクエストのそれぞれの部分から値を設定します。
use axum::{Json, extract::{Path, Query}};
use serde::Deserialize;
#[derive(Deserialize)]
struct Q { sort: String }
#[derive(Deserialize)]
struct B { name: String }
async fn h(Path(id): Path<u32>, Query(q): Query<Q>, Json(b): Json<B>) -> String {
format!("{} {} {}", id, q.sort, b.name)
}理解度チェック
extractor についての理解度を確認しましょう。
まとめ
extractor を使ってリクエストを解析する方法を学びました。
- URL セグメントには
Path、クエリ文字列にはQueryを使う - ボディには
Jsonを使う(最後に置く必要がある) - ヘッダーには
HeaderMapを使う OptionとResultで失敗を適切に処理する
次は、共有状態と JSON レスポンスについて学びます。
よくある質問
「エクストラクター」レッスンは無料ですか?
はい。「エクストラクター」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。
「エクストラクター」で何を学びますか?
リクエストを解析します ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Learn Rust Codingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「エクストラクター」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLearn Rust Codingレッスンでコードを書いて実行できますか?
はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Axumのルーティング
- エクストラクター
- JSONと状態
- ミドルウェア