REST API с Actix-web/Rocket
Разрабатывайте RESTful API с помощью современного веб-фреймворка Rust, например Actix-web или Rocket, обрабатывая маршруты, запросы и ответы.
«REST API с Actix-web/Rocket» — бесплатный урок Learn Rust Coding на CoddyKit. Это урок 1 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Learn Rust Coding, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Learn Rust Coding содержит 3 уроков всего.
Что такое REST API?
REST, или REpresentational State Transfer, — это архитектурный стиль сетевых приложений. Он определяет набор принципов взаимодействия веб-сервисов.
Представьте его как набор рекомендаций по созданию веб-сервисов, которые не хранят состояние, поддерживают кэширование и используют стандартные методы HTTP для взаимодействия с ресурсами.
- Ресурсы: Всё, что можно назвать, например пользователь, товар или заказ.
- URI: Уникальные идентификаторы ресурсов (например,
/users/123). - Методы HTTP: Стандартные действия, выполняемые над ресурсами (GET, POST, PUT, DELETE).
Почему Rust подходит для веб-сервисов?
Rust предоставляет уникальные преимущества для разработки веб-сервисов, поэтому это отличный выбор для высокопроизводительных и надёжных API:
- Производительность: Абстракции Rust без дополнительных затрат позволяют создавать высокоэффективный код, часто сопоставимый с кодом на C/C++.
- Безопасность памяти: Система владения предотвращает распространённые ошибки, такие как разыменование нулевых указателей и гонки данных, благодаря чему сервисы становятся надёжнее.
- Параллелизм: Модель async/await в Rust в сочетании с гарантиями безопасности позволяет без опасений создавать веб-сервисы, обрабатывающие множество задач одновременно.
- Надёжность: Строгая система типов и проверки во время компиляции позволяют выявлять многие ошибки на раннем этапе.
Знакомство с Actix-web
Для создания веб-сервисов на Rust часто используются фреймворки. Actix-web — мощный, практичный и чрезвычайно быстрый веб-фреймворк для Rust.
Он построен поверх Actix — фреймворка на основе акторов, однако для эффективного использования Actix-web не обязательно понимать устройство акторов. Фреймворк предназначен для асинхронных операций, поэтому отлично подходит для задач, ограниченных вводом-выводом, например для обработки множества одновременных запросов API.
Actix-web предоставляет средства для маршрутизации, обработки запросов и ответов, промежуточного программного обеспечения и многого другого, упрощая создание сложных API.
Настройка проекта и зависимостей
Для начала создадим новый проект на Rust и добавим необходимые зависимости. Мы будем использовать actix-web в качестве фреймворка и serde для сериализации и десериализации данных JSON.
Сначала создайте новый проект:
cargo new my_rest_api --bin
Затем добавьте следующие строки в файл Cargo.toml в разделе [dependencies]:
[dependencies]
actix-web = "4"
serde = { version = "1.0", features = ["derive"] }
Ваш первый сервер на Actix-web
Напишем минимальный сервер на Actix-web. Этот код настраивает базовую структуру для прослушивания входящих HTTP-запросов на порте 8080. Пока сервер не обрабатывает конкретные маршруты, но это его основа.
Макрос #[actix_web::main] делает нашу функцию async fn main совместимой со средой выполнения Actix-web.
use actix_web::{App, HttpServer};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server running at http://127.0.0.1:8080");
HttpServer::new(|| {
// Our application instance, where we'll add routes
App::new()
})
.bind(("127.0.0.1", 8080))? // Bind to an IP address and port
.run() // Start the server
.await // Await its completion
}Определение маршрута GET
Теперь добавим простой маршрут на наш сервер. Маршрут сопоставляет путь и метод входящего HTTP-запроса (например, GET /hello) с определённой функцией-обработчиком.
Наша функция-обработчик hello_world просто возвращает строку. Вызов web::get().to() регистрирует этот обработчик для GET-запросов к пути /hello.
use actix_web::{web, App, HttpServer, Responder};
// A handler function that returns a simple string response
async fn hello_world() -> impl Responder {
"Hello, Actix-web!"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server running at http://127.0.0.1:8080");
HttpServer::new(|| {
App::new()
// Register our route: GET /hello maps to hello_world()
.route("/hello", web::get().to(hello_world))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}Параметры пути для динамических маршрутов
API часто должны обрабатывать динамические части URL, например ID или имя. Actix-web использует параметры пути, чтобы извлекать эти значения.
Мы задаём в маршруте заполнитель (например, /{name}). В обработчике используем web::Path<String> (или любой другой тип, который можно десериализовать), чтобы извлечь значение.
use actix_web::{web, App, HttpServer, Responder};
// Handler function with a path parameter 'name'
async fn greet_name(name: web::Path<String>) -> impl Responder {
format!("Hello, {}!", name.into_inner())
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server running at http://127.0.0.1:8080");
HttpServer::new(|| {
App::new()
// Route with a dynamic path segment for a name
.route("/greet/{name}", web::get().to(greet_name))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}Обработка POST-запросов и JSON
Для создания или обновления ресурсов используются запросы POST или PUT; данные при этом часто передаются в теле запроса в формате JSON.
Actix-web упрощает обработку JSON с помощью web::Json<T>. Мы определяем структуру Rust struct, соответствующую ожидаемой структуре JSON, добавляем Deserialize из serde, и Actix-web автоматически разбирает входящий JSON в нашу структуру.
use actix_web::{web, App, HttpServer, Responder};
use serde::{Deserialize, Serialize};
// Define a struct to represent our incoming JSON data
#[derive(Deserialize, Serialize)]
struct User {
username: String,
email: String,
}
// Handler for POST requests that accepts a JSON User object
async fn create_user(user: web::Json<User>) -> impl Responder {
// In a real app, you'd save this user to a database
format!("User created: {} ({})", user.username, user.email)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server running at http://127.0.0.1:8080");
HttpServer::new(|| {
App::new()
// POST /users expects a JSON body and maps to create_user()
.route("/users", web::post().to(create_user))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}Создание простого API с состоянием
Объединим изученное и создадим небольшое API, управляющее списком пользователей в памяти. Мы будем использовать web::Data, чтобы передавать состояние приложения (наш список пользователей) между обработчиками.
std::sync::Mutex обеспечивает безопасный изменяемый доступ к нашему Vec<User> из нескольких одновременно выполняющихся запросов. У нас будут конечные точки GET /users и POST /users.
use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use serde::{Deserialize, Serialize};
use std::sync::Mutex; // For shared mutable state
// Define a User struct that can be serialized/deserialized and cloned
#[derive(Deserialize, Serialize, Clone)]
struct User {
id: u32,
username: String,
email: String,
}
// Application state to hold our users and track next ID
struct AppState {
users: Mutex<Vec<User>>,
next_id: Mutex<u32>,
}
// Handler to get all users
async fn get_users(data: web::Data<AppState>) -> impl Responder {
let users = data.users.lock().unwrap(); // Acquire a lock
web::Json(users.clone()) // Return users as JSON
}
// Handler to create a new user
async fn create_user(
data: web::Data<AppState>,
new_user: web::Json<User>,
) -> impl Responder {
let mut users = data.users.lock().unwrap();
let mut next_id = data.next_id.lock().unwrap();
let user = User {
id: *next_id,
username: new_user.username.clone(),
email: new_user.email.clone(),
};
users.push(user.clone());
*next_id += 1; // Increment for the next user
HttpResponse::Created().json(user) // Return 201 Created status and user
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server running at http://127.0.0.1:8080");
// Create shared application state
let app_state = web::Data::new(AppState {
users: Mutex::new(vec![]), // Initialize with an empty user list
next_id: Mutex::new(1), // Start IDs from 1
});
HttpServer::new(move || { // 'move' closure to capture app_state
App::new()
.app_data(app_state.clone()) // Register shared state with the app
.route("/users", web::get().to(get_users))
.route("/users", web::post().to(create_user))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}Быстрая проверка знаний об API
Вы научились настраивать базовый сервер Actix-web и обрабатывать различные HTTP-запросы. Проверим, насколько хорошо Вы усвоили материал!
Итоги и следующие шаги
Отличная работа! Вы сделали первые шаги в создании RESTful API на Rust и Actix-web.
- Мы изучили основы REST API и узнали, почему Rust отлично подходит для этой задачи.
- Вы научились настраивать базовый проект на Actix-web.
- Мы рассмотрели определение маршрутов GET и POST.
- Вы увидели, как извлекать параметры пути и обрабатывать данные JSON.
- Наконец, Вы создали простое API, управляющее состоянием в памяти с помощью
web::Data.
Далее Вы подробнее изучите интеграцию с базами данных и надёжную обработку ошибок, чтобы создавать ещё более мощные веб-сервисы, готовые к использованию в производственной среде!
Часто задаваемые вопросы
Урок «REST API с Actix-web/Rocket» бесплатный?
Да — полный текст урока «REST API с Actix-web/Rocket» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Learn Rust Coding, подпишись на CoddyKit PRO. Курс Learn Rust Coding содержит 3 уроков всего.
Чему я научусь в уроке «REST API с Actix-web/Rocket»?
Разрабатывайте RESTful API с помощью современного веб-фреймворка Rust, например Actix-web или Rocket, обрабатывая маршруты, запросы и ответы. Ты практикуешь Learn Rust Coding с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Learn Rust Coding?
Предыдущий опыт не требуется. Learn Rust Coding на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 3.
Сколько времени занимает урок «REST API с Actix-web/Rocket»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Learn Rust Coding?
Да. Каждый урок Learn Rust Coding включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- REST API с Actix-web/Rocket
- Интеграция с базами данных (SQLx/Diesel)
- Аутентификация и авторизация