Começo Rápido

Instalando o Rust

Se você ainda não instalou o Rust, pode usar o rustup fornecido oficialmente para instalar o Rust.

Tutorial Oficial do RustDetalhes sobre como instalar o Rust
TIP

A versão mínima do Rust suportada atualmente pelo Salvo é 1.85. Execute rustup updatepara confirmar que você possui uma versão compatível do Rust.

Escrevendo seu primeiro programa em Salvo

Crie um novo projeto:

cargo new hello --bin

Adicione as dependências ao 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"

No main.rs, crie um manipulador de função simples chamado hello, que apenas imprime o 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;
}

Parabéns, seu primeiro programa em Salvo está pronto. Basta executar cargo run no terminal e abrir http://127.0.0.1:5800 no navegador.

Explicação detalhada

Aqui, hello_world é um Handler, usado para processar solicitações do usuário. #[handler] permite que uma função implemente facilmente o trait Handler. Além disso, ele nos permite abreviar os parâmetros da função de diferentes maneiras.

  • Forma original:

    #[handler]
    async fn hello(_req: &mut Request, _depot: &mut Depot, res: &mut Response, _ctrl: &mut FlowCtrl) {
        res.render("Hello world");
    }
  • Você pode omitir parâmetros não utilizados na função, como _req, _depot e _ctrl, que não estão sendo usados aqui, e simplesmente não escrevê-los:

    #[handler]
    async fn hello(res: &mut Response) {
        res.render("Hello world");
    }
  • Qualquer tipo pode ser usado como tipo de retorno de uma função, desde que implemente o trait Writer. Por exemplo, &str implementa Writer e, quando retornado, imprime texto simples:

    #[handler]
    async fn hello(res: &mut Response) -> &'static str {
        "Hello world"
    }
  • O caso mais comum é quando precisamos usar Result<T, E> como tipo de retorno para lidar com erros durante a execução da função. Se T e E implementarem Writer, então Result<T, E> pode ser usado como valor de retorno:

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

HTTP3 Elegante

Dizem que o HTTP3 é leve como uma pena, muitos programadores sonham com ele, mas não conseguem alcançá-lo. Desta vez, o Salvo realiza esse desejo, permitindo que você desfrute facilmente dos serviços maravilhosos do HTTP3!

Primeiro, ative o recurso HTTP3 no Cargo.toml e, em seguida, modifique o main.rs da seguinte forma:

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

Ferramenta CLI do Salvo 🛠️

Salvo CLI é uma ferramenta projetada para o framework web Salvo, capaz de criar códigos limpos e legíveis, economizando seu tempo para coisas mais interessantes na vida.

Se você tiver ideias para melhorar o CLI ou encontrar problemas que precisam ser resolvidos, não hesite! Abra um issue, suas contribuições são bem-vindas.

Passo 1

Instale a ferramenta CLI:

cargo install salvo-cli

Passo 2

Crie um novo projeto Salvo usando o comando new seguido do nome do seu projeto:

salvo new nome_do_projeto

Com esta simples ferramenta CLI, você pode iniciar rapidamente um projeto Salvo, focando na implementação da lógica de negócios em vez de configurar a estrutura do projeto. ✨

Mais Exemplos

Recomenda-se clonar o repositório do Salvo e executar os exemplos no diretório examples. Por exemplo, o comando abaixo executa o exemplo hello:

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

O diretório examples contém muitos exemplos. Todos podem ser executados com comandos semelhantes a cargo run --bin example-<nome>.