0Pricing
Learn Rust Coding · 课时

JSON 与状态

共享状态与序列化

JSON 与状态 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 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 提取器传递它。

定义应用状态

定义一个保存共享数据的结构体。它通常会包装一个 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 参数,即可在处理函数中接收状态的克隆。

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 后修改数据

锁定互斥锁,修改值,然后让保护对象自动释放。这个可运行示例模拟了处理函数会执行的递增操作。

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,这样处理函数就可以只提取所需的部分。

use axum::extract::FromRef;

#[derive(Clone)]
struct Pool;

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

快速检查

测试您对 JSON 和状态的理解。

总结

您已经学习了 JSON 和共享状态:

  • 将 Serialize 类型包装在 Json 中以返回响应
  • 定义一个 Clone 状态结构体,通常包装 Arc
  • 使用 with_state 附加状态,使用 State 读取状态
  • 使用 Arc<Mutex> 保存可变共享数据,并使用 FromRef 处理子状态

下一步:使用 tower 层实现中间件。

常见问题解答

「JSON 与状态」课时是免费的吗?

是的 — 「JSON 与状态」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。

「JSON 与状态」这节课中我会学到什么?

共享状态与序列化 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 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