Início Rápido

Instalar Rust

Se ainda não instalou o Rust, pode usar a ferramenta oficial (rustup)[https://doc.rust-lang.org/book/ch01-01-installation.html] para instalar.

Tip

A versão mínima do Rust suportada pelo Salvo é 1.89. Execute rustup update para garantir que tem uma versão compatível instalada.

Escreva o Seu Primeiro Programa em Salvo

Crie um novo projeto:

cargo new hello --bin

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

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

Parabéns! O seu primeiro programa Salvo está completo. Basta executar cargo run na linha de comandos e depois abrir http://127.0.0.1:8698 no seu navegador.

Explicação Detalhada

Aqui, hello_world é um Handler usado para processar pedidos dos utilizadores. O atributo #[handler] permite que uma função implemente convenientemente o trait Handler. Além disso, permite-nos escrever parâmetros de função de várias formas simplificadas.

  • Forma original:

    #[handler]
    async fn hello(_req: &mut Request, _depot: &mut Depot, res: &mut Response, _ctrl: &mut FlowCtrl) {
        res.render("Hello world");
    }
  • Pode omitir parâmetros não utilizados na função. Por exemplo, _req, _depot e _ctrl não são usados aqui e podem ser omitidos completamente:

    #[handler]
    async fn hello(res: &mut Response) {
        res.render("Hello world");
    }
  • Qualquer tipo pode ser usado como tipo de retorno da 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"
    }
  • Mais comummente, precisamos de usar Result<T, E> como tipo de retorno para lidar com erros durante a execução da função. Se tanto T como 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 é ágil como uma andorinha, um sonho que muitos programadores ansiaram mas não conseguiram alcançar. Desta vez, o Salvo torna-o realidade, permitindo que todos desfrutem sem esforço dos maravilhosos serviços trazidos pelo HTTP3!

Primeiro, ative a funcionalidade HTTP3 no Cargo.toml, depois modifique o main.rs da seguinte forma:

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

Ferramenta CLI do Salvo 🛠️

Salvo CLI é uma ferramenta concebida para o framework web Salvo. Ajuda a criar código limpo e legível, poupando o seu tempo para coisas mais interessantes na vida.

Se tiver ideias para melhorar a CLI ou notar problemas que precisam de correção, não hesite! Submeta uma issue — damos as boas-vindas às suas sugestões.

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, pode configurar rapidamente um projeto Salvo, permitindo que se concentre na implementação da sua lógica de negócio em vez da configuração da estrutura do projeto. ✨

Mais Exemplos

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

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

Existem muitos exemplos no diretório examples. Pode executá-los usando comandos como cargo run --bin example-<nome>.