0Pricing
Learn Rust Coding · Урок

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 — локальная установка не требуется.

Все уроки этого курса

  1. REST API с Actix-web/Rocket
  2. Интеграция с базами данных (SQLx/Diesel)
  3. Аутентификация и авторизация
← Назад к Learn Rust Coding