JSON и состояние
Общее состояние и сериализация
«JSON и состояние» — бесплатный урок Learn Rust Coding на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения 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 }])
}Моделирование JSON в обычном Rust
Сериализация 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()
}Изменяемое общее состояние
Для изменяемых данных используйте блокировку, например Mutex внутри Arc. Это обеспечивает безопасное изменение данных из нескольких потоков.
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 и состояние» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Learn Rust Coding, подпишись на CoddyKit PRO. Курс Learn Rust Coding содержит 4 уроков всего.
Чему я научусь в уроке «JSON и состояние»?
Общее состояние и сериализация Ты практикуешь Learn Rust Coding с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Learn Rust Coding?
Предыдущий опыт не требуется. Learn Rust Coding на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «JSON и состояние»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Learn Rust Coding?
Да. Каждый урок Learn Rust Coding включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Маршрутизация Axum
- Извлекатели
- JSON и состояние
- Промежуточное ПО