Comenzando Rápidamente

Instalando Rust

Si aún no tienes Rust instalado, puedes usar rustup proporcionado oficialmente para instalarlo.

Tutorial Oficial de RustDetalles sobre cómo instalar Rust
TIP

La versión mínima de Rust soportada actualmente por Salvo es 1.85. Ejecuta rustup updatepara confirmar que tienes una versión compatible de Rust.

Escribiendo tu primer programa en Salvo

Crea un nuevo proyecto:

cargo new hello --bin

Añade las dependencias a Cargo.toml

hello/Cargo.toml
[package]
name = "example-hello"
version = "0.1.0"
edition = "2024"

[dependencies]
salvo = { version = "0.77.1" }
tokio = { version = "1", features = ["macros"] }
tracing = "0.1"
tracing-subscriber = "0.3"

En main.rs, crea un manejador de función simple llamado hello, que simplemente imprime el texto "Hello world".

hello/src/main.rs
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 5800
    let acceptor = TcpListener::new("0.0.0.0:5800").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! Has completado tu primer programa en Salvo. Solo ejecuta cargo run en la línea de comandos y abre http://127.0.0.1:5800 en tu navegador.

Explicación detallada

Aquí, hello_world es un Handler, utilizado para procesar solicitudes de usuario. #[handler] permite que una función implemente fácilmente el trait Handler. Además, permite abreviar los parámetros de la función de diferentes maneras.

  • Forma original:

    #[handler]
    async fn hello(_req: &mut Request, _depot: &mut Depot, res: &mut Response, _ctrl: &mut FlowCtrl) {
        res.render("Hello world");
    }
  • Puedes omitir parámetros no utilizados, como _req, _depot, _ctrl en este caso, y simplemente no escribirlos:

    #[handler]
    async fn hello(res: &mut Response) {
        res.render("Hello world");
    }
  • Cualquier tipo puede ser el 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"
    }
  • Es más común necesitar devolver 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 ser un tipo de retorno válido:

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

El elegante HTTP3

Se dice que HTTP3 es ligero como una pluma, muchos programadores lo desean pero no lo consiguen. ¡Esta vez, Salvo te ayuda a cumplir ese deseo, permitiéndote disfrutar fácilmente del maravilloso servicio que ofrece HTTP3!

Primero, habilita la función HTTP3 en Cargo.toml, luego modifica main.rs así:

main.rs
Cargo.toml
hello-h3/src/main.rs
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 5800
  let listener = TcpListener::new(("0.0.0.0", 5800)).rustls(config.clone());

  // Create QUIC listener and combine with TCP listener
  let acceptor = QuinnListener::new(config.build_quinn_config().unwrap(), ("0.0.0.0", 5800))
      .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, capaz de generar código limpio y legible, ahorrándote tiempo para cosas más interesantes en la vida.

Si tienes ideas para mejorar la CLI o encuentras problemas que necesitan solución, ¡no dudes en abrir un issue! Tus aportes son bienvenidos.

Paso 1

Instala la herramienta CLI:

cargo install salvo-cli

Paso 2

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

salvo new nombre_del_proyecto

Con esta sencilla herramienta CLI, puedes iniciar rápidamente un proyecto Salvo y centrarte en implementar tu lógica de negocio en lugar de en configurar 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

El directorio examples contiene muchos ejemplos. Todos pueden ejecutarse con comandos similares a cargo run --bin example-<nombre>.