0Pricing
Learn Rust Coding · Урок

Настройка проекта

Структура API

«Настройка проекта» — бесплатный урок Learn Rust Coding на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Learn Rust Coding, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Learn Rust Coding содержит 4 уроков всего.

Создание REST API на Rust

В этом курсе Вы создадите небольшое REST API на Rust. Мы используем веб-фреймворк Axum, построенный на Tokio (асинхронной среде выполнения) и Tower (промежуточном программном обеспечении). Он удобен, безопасен с точки зрения типов и широко используется в промышленной разработке.

В этом первом уроке создаётся структура проекта, чтобы в следующих уроках можно было добавить маршруты, модели, базу данных и тесты.

Создание проекта

Начните с Cargo. Бинарный проект предоставляет точку входа src/main.rs:

  • cargo new rest_api создаёт папку.
  • cd rest_api переходит в неё.
  • cargo run собирает и запускает проект.

Это команды оболочки и Cargo, а не запускаемые фрагменты Rust.

// terminal
// cargo new rest_api
// cd rest_api
// cargo run

Добавление зависимостей

Для API на Axum нужны несколько ящиков в Cargo.toml:

  • axum — для маршрутизации и обработчиков.
  • tokio — для асинхронной среды выполнения.
  • serde — для сериализации JSON.
// Cargo.toml
// [dependencies]
// axum = "0.7"
// tokio = { version = "1", features = ["full"] }
// serde = { version = "1", features = ["derive"] }
// serde_json = "1"

Асинхронная среда выполнения

Веб-серверы одновременно обрабатывают множество подключений, поэтому Axum является асинхронным. Атрибут #[tokio::main] превращает асинхронную main в настоящую точку входа, запуская среду выполнения Tokio. Каждый обработчик может использовать .await для неблокирующего ввода-вывода.

// src/main.rs
use tokio;

#[tokio::main]
async fn main() {
    println!("runtime started");
}

Минимальный сервер

Самое маленькое приложение Axum создаёт Router, привязывает TCP-слушатель и запускает обслуживание. Один маршрут связывает GET / с обработчиком, возвращающим строку. Обработчики — это обычные асинхронные функции, возвращающие значение, реализующее IntoResponse.

use axum::{routing::get, Router};

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(root));
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn root() -> &'static str {
    "Hello, API!"
}

Как работает маршрутизация

Router связывает путь и HTTP-метод с обработчиком. Цепочкой вызовов .route(path, method(handler)) регистрируйте конечные точки. Вспомогательные функции методов, такие как get, post, put и delete, находятся в axum::routing. Можно объединять несколько методов для одного пути.

use axum::{routing::{get, post}, Router};

async fn list() -> &'static str { "list" }
async fn create() -> &'static str { "created" }

fn build_router() -> Router {
    Router::new()
        .route("/items", get(list).post(create))
        .route("/health", get(|| async { "ok" }))
}

Рекомендуемая структура модулей

По мере роста API разделяйте код на модули, а не храните всё в одном огромном main.rs:

  • main.rs — запуск и настройка сервера.
  • routes.rs — определение маршрутизатора.
  • handlers.rs — обработчики запросов.
  • models.rs — структуры данных.

Такое разделение позволяет сосредоточить каждый файл на одной задаче и упростить его тестирование.

// src/main.rs
mod routes;
mod handlers;
mod models;

#[tokio::main]
async fn main() {
    let app = routes::build();
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Общее состояние приложения

Большинству API требуется общее состояние, например пул подключений к базе данных или хранилище в памяти. Axum хранит его в маршрутизаторе с помощью .with_state(state). Обработчики получают его через извлекатель State. Состояние должно поддерживать Clone; изменяемые данные следует обернуть в Arc и блокировку.

use axum::{routing::get, Router, extract::State};
use std::sync::{Arc, Mutex};

type Db = Arc<Mutex<Vec<String>>>;

async fn count(State(db): State<Db>) -> String {
    let n = db.lock().unwrap().len();
    format!("{} items", n)
}

fn build(db: Db) -> Router {
    Router::new().route("/count", get(count)).with_state(db)
}

Возврат JSON

Чтобы отправить JSON, оберните сериализуемое значение в axum::Json. Если с помощью serde вывести Serialize для Ваших структур, Axum автоматически установит правильный тип содержимого и тело ответа.

use axum::Json;
use serde::Serialize;

#[derive(Serialize)]
struct Status {
    service: String,
    healthy: bool,
}

async fn health() -> Json<Status> {
    Json(Status { service: "api".into(), healthy: true })
}

Конфигурация и порты

Жёстко заданный порт подходит для демонстраций, но реальные службы считывают конфигурацию из окружения. Используйте std::env::var со значением по умолчанию. Это позволяет менять адрес привязки без повторной сборки и удобно работать с контейнерами.

use std::env;

async fn main_inner() {
    let port = env::var("PORT").unwrap_or_else(|_| "3000".to_string());
    let addr = format!("0.0.0.0:{}", port);
    println!("binding to {}", addr);
    // bind and serve with addr ...
}

Объединение настройки

Полная настройка включает всё необходимое: создать маршрутизатор с маршрутами и общим состоянием, прочитать порт, привязать слушатель и запустить обслуживание. Теперь, когда каркас готов, в следующих уроках можно добавить настоящие конечные точки, модели и сохранение данных.

use axum::{routing::get, Router};
use std::sync::{Arc, Mutex};

#[tokio::main]
async fn main() {
    let db = Arc::new(Mutex::new(Vec::<String>::new()));
    let app = Router::new()
        .route("/health", get(|| async { "ok" }))
        .with_state(db);
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете настройку проекта.

Итоги

Вы настроили проект REST API на Rust:

  • Используйте cargo new и добавьте axum, tokio и serde.
  • #[tokio::main] предоставляет асинхронную среду выполнения.
  • Router связывает пути и методы с асинхронными обработчиками.
  • Делитесь данными с помощью .with_state и извлекателя State.
  • Разделяйте код на модули маршрутов, обработчиков и моделей; считывайте порт из окружения.

Часто задаваемые вопросы

Урок «Настройка проекта» бесплатный?

Да — полный текст урока «Настройка проекта» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Learn Rust Coding, подпишись на CoddyKit PRO. Курс Learn Rust Coding содержит 4 уроков всего.

Чему я научусь в уроке «Настройка проекта»?

Структура API Ты практикуешь Learn Rust Coding с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Learn Rust Coding?

Предыдущий опыт не требуется. Learn Rust Coding на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Настройка проекта»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Learn Rust Coding?

Да. Каждый урок Learn Rust Coding включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

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

  1. Настройка проекта
  2. Конечные точки и модели
  3. Интеграция с базой данных
  4. Тестирование API
← Назад к Learn Rust Coding