Inicio Rápido

Instalar Rust

Si aún no has instalado Rust, puedes usar la herramienta oficial (rustup)[https://doc.rust-lang.org/book/ch01-01-installation.html] para instalarlo.

Tip

La versión mínima de Rust compatible con Salvo es 1.89. Ejecuta rustup update para asegurarte de tener instalada una versión compatible.

Escribe tu primer programa en Salvo

Crea un nuevo proyecto:

cargo new hello --bin

Añade las dependencias en 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

En main.rs, crea un manejador de función simple llamado hello, que simplemente imprime el texto "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;
}

¡Felicidades! Tu primer programa en Salvo está completo. Solo ejecuta cargo run en la línea de comandos y luego abre http://127.0.0.1:8698 en tu navegador.

Explicación Detallada

Aquí, hello_world es un Handler utilizado para procesar las solicitudes del usuario. El atributo #[handler] permite que una función implemente convenientemente el trait Handler. Además, nos permite escribir parámetros de función de varias formas simplificadas.

  • Forma original:

    #[handler]
    async fn hello(_req: &mut Request, _depot: &mut Depot, res: &mut Response, _ctrl: &mut FlowCtrl) {
        res.render("Hello world");
    }
  • Puedes omitir los parámetros no utilizados en la función. Por ejemplo, _req, _depot y _ctrl no se usan aquí y se pueden omitir por completo:

    #[handler]
    async fn hello(res: &mut Response) {
        res.render("Hello world");
    }
  • Cualquier tipo puede usarse como tipo de retorno de la función siempre que implemente el trait Writer. Por ejemplo, &str implementa Writer, y cuando se devuelve, imprime texto plano:

    #[handler]
    async fn hello(res: &mut Response) -> &'static str {
        "Hello world"
    }
  • Más comúnmente, necesitamos usar Result<T, E> como tipo de retorno para manejar errores durante la ejecución de la función. Si tanto T como E implementan Writer, entonces Result<T, E> puede usarse como valor de retorno:

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

HTTP3 Ágil

Dicen que HTTP3 es ágil como una golondrina, un sueño que muchos programadores han anhelado pero no han podido alcanzar. Esta vez, Salvo lo hace realidad, ¡permitiendo que todos disfruten sin esfuerzo de los maravillosos servicios que trae HTTP3!

Primero, habilita la función HTTP3 en Cargo.toml, luego modifica main.rs de la siguiente manera:

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

Herramienta CLI de Salvo 🛠️

Salvo CLI es una herramienta diseñada para el framework web Salvo. Ayuda a crear código limpio y legible, ahorrando tu tiempo para cosas más interesantes en la vida.

Si tienes ideas para mejorar la CLI o notas problemas que necesitan solución, ¡no dudes! Envía un issue—agradecemos tus aportes.

Paso 1

Instala la herramienta CLI:

cargo install salvo-cli

Paso 2

Crea un nuevo proyecto de Salvo usando el comando new seguido del nombre de tu proyecto:

salvo new nombre_del_proyecto

Con esta sencilla herramienta CLI, puedes configurar rápidamente un proyecto de Salvo, permitiéndote centrarte en implementar tu lógica de negocio en lugar de en la configuración de la estructura del proyecto. ✨

Más Ejemplos

Se recomienda clonar directamente el repositorio de Salvo y ejecutar los ejemplos en el directorio examples. Por ejemplo, el siguiente comando ejecuta el ejemplo hello:

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

Hay muchos ejemplos en el directorio examples. Puedes ejecutarlos usando comandos como cargo run --bin example-<nombre>.