Guida Rapida

Installa Rust

Se non hai ancora installato Rust, puoi utilizzare lo strumento ufficiale (rustup)[https://doc.rust-lang.org/book/ch01-01-installation.html] per installare Rust.

Tip

La versione minima di Rust supportata da Salvo è la 1.89. Esegui rustup update per assicurarti di avere una versione compatibile di Rust installata.

Scrivi il Tuo Primo Programma con Salvo

Crea un nuovo progetto:

cargo new hello --bin

Aggiungi le dipendenze al file Cargo.toml:

[package]
name = "example-hello"
version.workspace = true
edition.workspace = true
publish.workspace = true
rust-version.workspace = true

[dependencies]
salvo = { workspace = true }
tokio = { workspace = true, features = ["macros"] }
tracing.workspace = true
tracing-subscriber.workspace = true

In main.rs, crea un semplice gestore di funzione chiamato hello, che stampa semplicemente il testo "Hello world".

use salvo::prelude::*;

// Handler for English greeting
#[handler]
async fn hello() -> &'static str {
    "Hello World"
}

// Handler for Chinese greeting
#[handler]
async fn hello_zh() -> Result<&'static str, ()> {
    Ok("你好,世界!")
}

#[tokio::main]
async fn main() {
    // Initialize logging subsystem
    tracing_subscriber::fmt().init();

    // Bind server to port 8698
    let acceptor = TcpListener::new("0.0.0.0:8698").bind().await;

    // Create router with two endpoints:
    // - / (root path) returns English greeting
    // - /你好 returns Chinese greeting
    let router = Router::new()
        .get(hello)
        .push(Router::with_path("你好").get(hello_zh));

    // Print router structure for debugging
    println!("{router:?}");

    // Start serving requests
    Server::new(acceptor).serve(router).await;
}

Congratulazioni! Il tuo primo programma con Salvo è completo. Basta eseguire cargo run nella riga di comando, quindi aprire http://127.0.0.1:8698 nel tuo browser.

Spiegazione Dettagliata

Qui, hello_world è un Handler utilizzato per elaborare le richieste degli utenti. L'attributo #[handler] consente a una funzione di implementare facilmente il tratto Handler. Inoltre, ci permette di scrivere i parametri della funzione in vari modi semplificati.

  • Forma originale:

    #[handler]
    async fn hello(_req: &mut Request, _depot: &mut Depot, res: &mut Response, _ctrl: &mut FlowCtrl) {
        res.render("Hello world");
    }
  • Puoi omettere i parametri non utilizzati nella funzione. Ad esempio, _req, _depot e _ctrl non sono utilizzati qui e possono essere completamente omessi:

    #[handler]
    async fn hello(res: &mut Response) {
        res.render("Hello world");
    }
  • Qualsiasi tipo può essere utilizzato come tipo di ritorno della funzione, purché implementi il tratto Writer. Ad esempio, &str implementa Writer e, quando restituito, stampa testo semplice:

    #[handler]
    async fn hello(res: &mut Response) -> &'static str {
        "Hello world"
    }
  • Più comunemente, abbiamo bisogno di utilizzare Result<T, E> come tipo di ritorno per gestire gli errori durante l'esecuzione della funzione. Se sia T che E implementano Writer, allora Result<T, E> può essere utilizzato come valore di ritorno:

    #[handler]
    async fn hello(res: &mut Response) -> Result<&'static str, ()> {
        Ok("Hello world")
    }

HTTP3 Agilissimo

Si dice che HTTP3 sia agile come una rondine, un sogno che molti programmatori hanno desiderato ma non hanno potuto realizzare. Questa volta, Salvo lo rende possibile, permettendo a tutti di godere senza sforzo dei meravigliosi servizi offerti da HTTP3!

Prima, abilita la funzionalità HTTP3 in Cargo.toml, quindi modifica main.rs come segue:

main.rs
Cargo.toml
use salvo::conn::rustls::{Keycert, RustlsConfig};
use salvo::prelude::*;

// Handler function responding with "Hello World" for HTTP/3 requests
#[handler]
async fn hello() -> &'static str {
    "Hello World"
}

#[tokio::main]
async fn main() {
    // Initialize logging system
    tracing_subscriber::fmt().init();

    // Load TLS certificate and private key from embedded PEM files
    let cert = include_bytes!("../certs/cert.pem").to_vec();
    let key = include_bytes!("../certs/key.pem").to_vec();

    // Create router with single endpoint
    let router = Router::new().get(hello);

    // Configure TLS settings using Rustls
    let config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));

    // Create TCP listener with TLS encryption on port 8698
    let listener = TcpListener::new(("0.0.0.0", 8698)).rustls(config.clone());

    // Create QUIC listener and combine with TCP listener
    let acceptor = QuinnListener::new(config.build_quinn_config().unwrap(), ("0.0.0.0", 8698))
        .join(listener)
        .bind()
        .await;

    // Start server supporting both HTTP/3 (QUIC) and HTTPS (TCP)
    Server::new(acceptor).serve(router).await;
}

Strumento CLI di Salvo 🛠️

Salvo CLI è uno strumento progettato per il framework web Salvo. Aiuta a creare codice pulito e leggibile, risparmiando il tuo tempo per cose più interessanti nella vita.

Se hai idee per migliorare la CLI o noti problemi che devono essere risolti, non esitare! Invia un issue: le tue intuizioni sono benvenute.

Passo 1

Installa lo strumento CLI:

cargo install salvo-cli

Passo 2

Crea un nuovo progetto Salvo utilizzando il comando new seguito dal nome del tuo progetto:

salvo new nome_progetto

Con questo semplice strumento CLI, puoi configurare rapidamente un progetto Salvo, permettendoti di concentrarti sull'implementazione della tua logica di business piuttosto che sulla configurazione della struttura del progetto. ✨

Altri Esempi

Si consiglia di clonare direttamente il repository di Salvo ed eseguire gli esempi nella directory examples. Ad esempio, il seguente comando esegue l'esempio hello:

git clone https://github.com/salvo-rs/salvo
cd salvo/examples
cargo run --bin example-hello

Ci sono molti esempi nella directory examples. Puoi eseguirli utilizzando comandi come cargo run --bin example-<nome>.