0Pricing
Learn Rust Coding · レッスン

JSONと状態

共有状態とシリアライゼーション

「JSONと状態」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。

JSON を返す

Axum では JSON レスポンスを簡単に返せます。Serialize を実装した型を Json で包むと、コンテンツタイプの設定とボディのシリアライズが行われます。

use axum::Json;
use serde::Serialize;

#[derive(Serialize)]
struct User { id: u32, name: String }

async fn get_user() -> Json<User> {
    Json(User { id: 1, name: "Alice".into() })
}

コレクションをシリアライズする

シリアライズ可能な項目の Vec は JSON 配列になります。追加の作業は必要ありません。

use axum::Json;
use serde::Serialize;

#[derive(Serialize)]
struct Item { id: u32 }

async fn list() -> Json<Vec<Item>> {
    Json(vec![Item { id: 1 }, Item { id: 2 }])
}

通常の Rust で JSON をモデル化する

JSON のシリアライズとは、構造体を文字列に変換することです。serde_json では to_string を呼び出します。ここでは手動のフォーマットを使って、その考え方を示します。

struct User { id: u32, name: String }

fn to_json(u: &User) -> String {
    format!("{{\"id\":{},\"name\":\"{}\"}}", u.id, u.name)
}

fn main() {
    let u = User { id: 1, name: "Alice".to_string() };
    println!("{}", to_json(&u));
}

共有状態とは

共有状態は、データベースプールや設定など、すべてのハンドラーからアクセスできるデータです。Axum では State extractor を使って共有状態を渡します。

アプリケーション状態を定義する

共有データを保持する構造体を定義します。多くの場合、安価に clone できるように Arc で包みます。

use std::sync::Arc;

#[derive(Clone)]
struct AppState {
    name: Arc<String>,
}

ルーターに状態を付加する

with_state に状態を渡します。Axum が状態を保持し、それを要求するハンドラーに提供します。

use axum::{Router, routing::get};

async fn handler() -> &'static str { "ok" }

fn app(state: AppState) -> Router {
    Router::new().route("/", get(handler)).with_state(state)
}

ハンドラーで状態を読み取る

State パラメーターを追加すると、ハンドラー内で状態の clone を受け取れます。

use axum::extract::State;

async fn handler(State(state): State<AppState>) -> String {
    state.name.to_string()
}

可変な共有状態

変化するデータは、Arc の中に Mutex などのロックを置いて保護します。これにより、安全に同時変更できます。

use std::sync::{Arc, Mutex};

#[derive(Clone)]
struct Counter {
    count: Arc<Mutex<u32>>,
}

Mutex の内部を変更する

mutex をロックして値を変更し、その後ガードを破棄します。この実行可能な例では、ハンドラーが行うインクリメント処理を再現しています。

use std::sync::{Arc, Mutex};

fn main() {
    let count = Arc::new(Mutex::new(0u32));
    {
        let mut guard = count.lock().unwrap();
        *guard += 1;
    }
    println!("count = {}", *count.lock().unwrap());
}

JSON を受け取り、エコーする

入力と出力の JSON を組み合わせます。ボディをデシリアライズし、変換して、JSON として返します。作成してから応答する、よくあるパターンです。

use axum::Json;
use serde::{Serialize, Deserialize};

#[derive(Deserialize)]
struct Input { name: String }
#[derive(Serialize)]
struct Output { greeting: String }

async fn greet(Json(i): Json<Input>) -> Json<Output> {
    Json(Output { greeting: format!("Hi {}", i.name) })
}

FromRef によるサブ状態

状態が複数の要素を持つ場合は、FromRef を derive すると、ハンドラーが必要な部分だけを抽出できます。

use axum::extract::FromRef;

#[derive(Clone)]
struct Pool;

#[derive(Clone, FromRef)]
struct AppState {
    pool: Pool,
}

理解度チェック

JSON と状態についての理解度を確認しましょう。

まとめ

JSON と共有状態について学びました。

  • Serialize 型を Json で包んでレスポンスを返す
  • Clone を derive した状態構造体を定義し、多くの場合 Arc で包む
  • with_state で状態を付加し、State で読み取る
  • 可変な共有データには Arc<Mutex> を、サブ状態には FromRef を使う

次は、tower のレイヤーを使ったミドルウェアについて学びます。

よくある質問

「JSONと状態」レッスンは無料ですか?

はい。「JSONと状態」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。

「JSONと状態」で何を学びますか?

共有状態とシリアライゼーション ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Learn Rust Codingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「JSONと状態」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLearn Rust Codingレッスンでコードを書いて実行できますか?

はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Axumのルーティング
  2. エクストラクター
  3. JSONと状態
  4. ミドルウェア
← Learn Rust Codingに戻る