0Pricing
Learn Rust Coding · Lezione

Configurazione del progetto

Strutturare l'API

Configurazione del progetto è una lezione Learn Rust Coding gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Learn Rust Coding, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Learn Rust Coding include 4 lezioni in totale.

Costruire una REST API in Rust

In questo corso costruirete una piccola REST API in Rust. Useremo il framework web Axum, basato su Tokio (runtime asincrono) e Tower (middleware). È ergonomico, type-safe e ampiamente utilizzato in produzione.

Questa prima lezione configura la struttura del progetto, così nelle lezioni successive sarà possibile aggiungere route, modelli, un database e test.

Creare il progetto

Iniziate con Cargo. Un progetto binario offre un punto di ingresso src/main.rs:

  • cargo new rest_api crea la cartella.
  • cd rest_api vi sposta al suo interno.
  • cargo run esegue la compilazione e l'avvio.

Questi sono comandi della shell e di cargo, non frammenti Rust eseguibili.

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

Aggiungere le dipendenze

Un'API Axum richiede alcuni crate in Cargo.toml:

  • axum per il routing e gli handler.
  • tokio per il runtime asincrono.
  • serde per la serializzazione JSON.
// Cargo.toml
// [dependencies]
// axum = "0.7"
// tokio = { version = "1", features = ["full"] }
// serde = { version = "1", features = ["derive"] }
// serde_json = "1"

Il runtime asincrono

I server web gestiscono molte connessioni simultaneamente, quindi Axum è async. L'attributo #[tokio::main] trasforma un main asincrono in un vero punto di ingresso avviando il runtime Tokio. Ogni handler può usare .await per eseguire I/O non bloccante.

// src/main.rs
use tokio;

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

Un server minimale

L'applicazione Axum più semplice crea un Router, associa un listener TCP e avvia il server. Un'unica route associa GET / a un handler che restituisce una stringa. Gli handler sono semplicemente funzioni asincrone che restituiscono un valore che implementa 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!"
}

Come funziona il routing

Un Router associa un percorso e un metodo HTTP a un handler. Concatenate le chiamate .route(path, method(handler)) per registrare gli endpoint. Gli helper per i metodi, come get, post, put e delete, provengono da axum::routing. Potete combinare più metodi sullo stesso percorso.

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

Struttura consigliata dei moduli

Quando l'API cresce, suddividete il codice in moduli invece di concentrarlo in un unico enorme main.rs:

  • main.rs — avvio e configurazione del server.
  • routes.rs — definizione del router.
  • handlers.rs — handler delle richieste.
  • models.rs — strutture dati.

Questa separazione mantiene ogni file focalizzato e facilmente testabile.

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

Stato condiviso dell'applicazione

La maggior parte delle API richiede uno stato condiviso, ad esempio un pool di connessioni al database o un archivio in memoria. Axum lo mantiene con .with_state(state) sul router. Gli handler lo ricevono tramite l'estrattore State. Lo stato deve essere Clone; racchiudete i dati mutabili in un Arc e in un lock.

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

Restituire JSON

Per inviare JSON, racchiudete un valore serializzabile in axum::Json. Se usate serde per derivare Serialize sulle vostre struct, Axum imposta automaticamente il tipo di contenuto e il body corretti.

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

Configurazione e porte

Impostare la porta direttamente nel codice va bene per le demo, ma i servizi reali leggono la configurazione dall'ambiente. Usate std::env::var con un valore predefinito. In questo modo potete cambiare l'indirizzo di binding senza ricompilare e lavorare meglio con i container.

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

Completare la configurazione

Un avvio completo collega tutti gli elementi: create il router con le route e lo stato condiviso, leggete la porta, associate un listener e avviate il server. Con questa struttura di base, nelle lezioni successive aggiungerete endpoint, modelli e persistenza reali.

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

Verifica rapida

Verificate la vostra comprensione della configurazione del progetto.

Riepilogo

Avete configurato un progetto di API REST in Rust:

  • Usate cargo new e aggiungete axum, tokio e serde.
  • #[tokio::main] fornisce il runtime asincrono.
  • Un Router associa percorsi e metodi a handler asincroni.
  • Condividete i dati con .with_state e l'estrattore State.
  • Suddividete il codice in moduli per route, handler e modelli; leggete la porta dall'ambiente.

Domande Frequenti

La lezione «Configurazione del progetto» è gratuita?

Sì — il testo completo di «Configurazione del progetto» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Learn Rust Coding, passa a CoddyKit PRO. Il corso Learn Rust Coding include 4 lezioni in totale.

Cosa imparerò in «Configurazione del progetto»?

Strutturare l'API Eserciti Learn Rust Coding con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Learn Rust Coding?

Non è richiesta alcuna esperienza precedente. Learn Rust Coding su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Configurazione del progetto»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Learn Rust Coding?

Sì. Ogni lezione Learn Rust Coding include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Configurazione del progetto
  2. Endpoint e modelli
  3. Integrazione con il database
  4. Test dell'API
← Torna a Learn Rust Coding