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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Axumのルーティング
- エクストラクター
- JSONと状態
- ミドルウェア