Клонируем title и body в JavaScript
Rust + Actix-web: Пишем API, которые летают и не падают
Честно говоря, большинство из нас хватается за Node.js или Python, когда нужно быстро запилить REST API. Все мы знаем эти вечные компромиссы: скорость разработки против производительности, прототип против продакшена. А что если можно получить и то, и другое?
Именно такой посыл несет Rust, а Actix-web делает его доступным для веб-разработчиков.
Почему Rust для API? (То, о чем все молчат)
Прежде чем написать хоть строчку кода, нужно поговорить о главном: у Rust есть порог входа. Он реально крутой. Borrow checker будет ставить вас на место. Вы будете тратить часы на отладку lifetime-ов вместо того, чтобы фигачить фичи.
Но вот что меня зацепило: Rust не заставляет выбирать между безопасностью и скоростью. Ваш API будет защищен от утечек памяти по умолчанию — никаких null pointer exceptions, никаких data races, никаких пауз от garbage collection, которые убивают ваш p99 latency. Когда вы обслуживаете тысячи запросов в секунду, эта предсказуемость критична.
Для стартапов и разработчиков, которые масштабируют системы, это означает стабильную производительность без необходимости городить дополнительные слои защиты.
Знакомство с Actix-web
Actix-web вдохновлен (но никак не связан) фреймворком Elixir/Phoenix. Он использует actor model и предоставляет удобный API, знакомый тем, кто работал с Express, Fastify и им подобными.
Настройка проекта
cargo new rust-api-demo
cd rust-api-demo
cargo add actix-web actix-rt
Первый эндпоинт
use actix_web::{web, App, HttpServer, HttpResponse};
async fn health_check() -> HttpResponse {
HttpResponse::Ok().json(serde_json::json!({
"status": "healthy",
"version": env!("CARGO_PKG_VERSION")
}))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/health", web::get().to(health_check))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Тот самый health endpoint? Компилируется за миллисекунды, запускается за микросекунды. Запускаете cargo run, стучитесь на localhost:8080/health — и мгновенно получаете JSON-ответ.
Реальный API: Todo с полным набором CRUD
Теперь давайте сделаем что-то посерьезнее — Todo API с полным набором операций.
Описываем модель данных
use serde::{Deserialize, Serialize};
use std::sync::Mutex;
use std::cell::Cell;
#[derive(Clone, Serialize, Deserialize)]
struct Todo {
id: u64,
title: String,
completed: bool,
}