0Pricing
Learn Rust Coding · Lekcja

Konfiguracja projektu

Strukturyzowanie API

Konfiguracja projektu to bezpłatna lekcja Learn Rust Coding na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Learn Rust Coding, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.

Budowanie interfejsu REST API w Rust

W tym kursie zbudujesz mały interfejs REST API w Rust. Używamy frameworka internetowego Axum, opartego na Tokio (asynchronicznym środowisku uruchomieniowym) i Tower (middleware). Jest ergonomiczny, bezpieczny typowo i szeroko stosowany w środowiskach produkcyjnych.

W tej pierwszej lekcji skonfigurujesz strukturę projektu, aby w kolejnych lekcjach można było dodać trasy, modele, bazę danych i testy.

Tworzenie projektu

Zacznij od Cargo. Projekt binarny udostępnia punkt wejścia src/main.rs:

  • cargo new rest_api tworzy folder.
  • cd rest_api przechodzi do tego folderu.
  • cargo run buduje projekt i go uruchamia.

Są to polecenia powłoki i Cargo, a nie fragmenty kodu Rust gotowe do uruchomienia.

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

Dodawanie zależności

Interfejs API w Axum potrzebuje kilku crate’ów w pliku Cargo.toml:

  • axum do routingu i handlerów.
  • tokio jako asynchroniczne środowisko uruchomieniowe.
  • serde do serializacji JSON.
// Cargo.toml
// [dependencies]
// axum = "0.7"
// tokio = { version = "1", features = ["full"] }
// serde = { version = "1", features = ["derive"] }
// serde_json = "1"

Asynchroniczne środowisko uruchomieniowe

Serwery internetowe obsługują wiele połączeń jednocześnie, dlatego Axum jest asynchroniczny. Atrybut #[tokio::main] zmienia asynchroniczną funkcję main w rzeczywisty punkt wejścia, uruchamiając środowisko uruchomieniowe Tokio. Każdy handler może używać .await do nieblokujących operacji wejścia-wyjścia.

// src/main.rs
use tokio;

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

Minimalny serwer

Najmniejsza aplikacja Axum tworzy Router, wiąże nasłuchujący port TCP i uruchamia serwer. Pojedyncza trasa mapuje GET / na handler zwracający ciąg znaków. Handlery to zwykłe funkcje asynchroniczne zwracające wartość implementującą 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!"
}

Jak działa routing

Obiekt Router mapuje ścieżkę i metodę HTTP na handler. Łącz wywołania .route(path, method(handler)), aby rejestrować endpointy. Pomocnicze funkcje metod, takie jak get, post, put i delete, pochodzą z axum::routing. Możesz łączyć metody dla tej samej ścieżki.

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" }))
}

Zalecany układ modułów

W miarę rozrastania się interfejsu API podziel kod na moduły zamiast umieszczać wszystko w jednym ogromnym pliku main.rs:

  • main.rs — uruchamianie i konfiguracja serwera.
  • routes.rs — definicja routera.
  • handlers.rs — handlery żądań.
  • models.rs — struktury danych.

Taki podział pozwala zachować przejrzystość każdego pliku i ułatwia jego testowanie.

// 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();
}

Współdzielony stan aplikacji

Większość interfejsów API potrzebuje współdzielonego stanu, takiego jak pula połączeń z bazą danych lub magazyn w pamięci. Axum przechowuje go za pomocą .with_state(state) na routerze. Handlery otrzymują go przez ekstraktor State. Stan musi implementować Clone; dane modyfikowalne należy opakować w Arc i blokadę.

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)
}

Zwracanie JSON

Aby wysłać JSON, opakuj wartość możliwą do serializacji w axum::Json. Gdy struktury mają wyprowadzoną implementację Serialize za pomocą serde, Axum automatycznie ustawia właściwy typ zawartości i treść odpowiedzi.

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 })
}

Konfiguracja i porty

Zakodowanie portu na stałe jest odpowiednie w demonstracjach, ale rzeczywiste usługi odczytują konfigurację ze środowiska. Użyj std::env::var wraz z wartością domyślną. Dzięki temu można zmienić adres nasłuchiwania bez ponownej kompilacji i zapewnić poprawną współpracę z kontenerami.

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 ...
}

Łączenie konfiguracji

Kompletna konfiguracja uruchomieniowa łączy wszystkie elementy: buduje router z trasami i współdzielonym stanem, odczytuje port, wiąże nasłuchujący port i uruchamia serwer. Mając ten szkielet, w kolejnych lekcjach dodasz rzeczywiste endpointy, modele i trwałe przechowywanie danych.

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();
}

Szybkie sprawdzenie

Sprawdź swoją wiedzę o konfiguracji projektu.

Podsumowanie

Skonfigurowano projekt interfejsu REST API w Rust:

  • Użyj cargo new i dodaj axum, tokio oraz serde.
  • #[tokio::main] zapewnia asynchroniczne środowisko uruchomieniowe.
  • Obiekt Router mapuje ścieżki i metody na asynchroniczne handlery.
  • Udostępniaj dane za pomocą .with_state i ekstraktora State.
  • Podziel kod na moduły tras, handlerów i modeli; odczytuj port ze środowiska.

Często zadawane pytania

Czy lekcja „Konfiguracja projektu” jest bezpłatna?

Tak — pełny tekst „Konfiguracja projektu” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Learn Rust Coding, przejdź na CoddyKit PRO. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.

Co nauczysz się w „Konfiguracja projektu”?

Strukturyzowanie API Ćwiczysz Learn Rust Coding z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Learn Rust Coding?

Nie wymagamy żadnego doświadczenia. Learn Rust Coding w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Konfiguracja projektu”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Learn Rust Coding?

Tak. Każda lekcja Learn Rust Coding zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Konfiguracja projektu
  2. Endpointy i modele
  3. Integracja z bazą danych
  4. Testowanie API
← Powrót do Learn Rust Coding