---
title: "Rocket Rust: Tutorial de API REST com Web Framework | Rust Brasil"
url: "https://rustlang.com.br/ecossistema/rocket/"
markdown_url: "https://rustlang.com.br/ecossistema/rocket.MD"
description: "Aprenda Rocket Rust 0.5: crie e teste seu primeiro servidor, use rotas, request guards, JSON, managed state, fairings e templates e avance para produção com exemplos em português."
date: "2026-10-09"
author: ""
---

# Rocket Rust: Tutorial de API REST com Web Framework | Rust Brasil

Aprenda Rocket Rust 0.5: crie e teste seu primeiro servidor, use rotas, request guards, JSON, managed state, fairings e templates e avance para produção com exemplos em português.


**Rocket é o framework web em Rust com a API mais declarativa do ecossistema: rotas definidas por macros de atributo, dados de requisição validados por tipos, estado compartilhado gerenciado pelo próprio framework e middleware (fairings) anexado explicitamente.** Desde a série **0.5**, o Rocket é assíncrono por completo, roda sobre o [Tokio](/ecossistema/tokio/) e trata a maioria das decisões de uma API web — validação de formulários, cookies, sessões, templates e pools de banco — com módulos oficiais em vez de escolhas manuais de crates.

Se você pesquisou **rocket rust**, **rocket framework** ou **rust web framework**, esta página explica o que o Rocket é, como instalar e como escrever sua primeira API — com exemplos em português e o mesmo caminho progressivo usado nos guias de [Axum](/ecossistema/axum/) e [Actix Web](/ecossistema/actix-web/).

```toml
# Começo mínimo
[dependencies]
rocket = "0.5"
serde = { version = "1", features = ["derive"] }
```

```rust
#[macro_use] extern crate rocket;

#[get("/")]
fn raiz() -> &'static str {
    "Olá, mundo!"
}

#[rocket::main]
async fn main() {
    let _ = rocket::build()
        .mount("/", routes![raiz])
        .launch()
        .await
        .expect("Falha ao iniciar o Rocket");
}
```

## Comece aqui: do projeto vazio ao primeiro servidor Rocket

Com [Rust e o Cargo instalados](/instalacao/), crie um projeto de estudo e adicione as dependências:

```bash
cargo new minha-api-rocket
cd minha-api-rocket
cargo add rocket serde --features serde/derive
```

Substitua o `src/main.rs` pelo exemplo Hello World acima e rode:

```bash
cargo run
```

O servidor sobe em `http://localhost:8000` (o endereço padrão do Rocket em ambiente debug) e o log do terminal mostra a tabela de rotas montadas — o framework imprime cada rota com o método, o caminho e o nome do handler. **Não é necessário instalar banco de dados nem configurar templates para testar a primeira rota.**

Antes de avançar, três diferenças de mentalidade em relação a [Axum](/ecossistema/axum/) e [Actix Web](/ecossistema/actix-web/):

1. **Rotas são atributos dos handlers.** O `#[get("/caminho")]` declara rota e handler juntos; não existe uma tabela central de rotas.
2. **Parâmetros são tipados na assinatura.** O Rocket infere o que cada argumento significa pelo tipo: `&str` em path, guard de query, `State<T>` etc.
3. **Middleware é attach, não wrap.** Comportamentos globais entram com `.attach(fairing)` em vez de envolver cada rota.

## Instalação

O Rocket 0.5 exige uma versão de Rust razoavelmente recente — recomenda-se manter a toolchain atualizada com [rustup](/ecossistema/rustup/):

```bash
rustup update stable
cargo add rocket
```

Dependências comuns conforme o guia avança:

```toml
[dependencies]
rocket = { version = "0.5", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
```

A feature `json` habilita o suporte nativo a corpos JSON via [Serde](/ecossistema/serde/): o extractor `Json<T>` para entrada e o responder para saída. Para templates dinâmicos, banco de dados, cookies privados e arquivos estáticos existem crates oficiais (`rocket_dyn_templates`, `rocket_db_pools`), apresentadas nas seções seguintes.

Verifique a instalação com o build de produção, que também mostra avisos de código morto:

```bash
cargo build --release
```

## Uso Básico

### Hello World

O menor servidor Rocket útil:

```rust
#[macro_use] extern crate rocket;

#[get("/")]
fn raiz() -> &'static str {
    "Olá, mundo!"
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![raiz])
}
```

A macro `#[launch]` é um atalho: ela gera o `main` assíncrono, sobe o servidor e gerencia o shutdown sozinha. Quando você precisa de controle fino (configurar endereço, aguardar shutdown graceful), troque para `#[rocket::main]` e chame `.launch().await` manualmente.

### Rotas, paths dinâmicos e query strings

Rotas declaram parâmetros dinâmicos direto no atributo. O tipo do argumento define como o valor é lido e validado:

```rust
use rocket::response::Debug;

#[get("/ola/<nome>")]
fn saudacao(nome: &str) -> String {
    format!("Olá, {}!", nome)
}

// Parâmetro tipado: um id inválido nem chega ao handler
#[get("/usuarios/<id>")]
fn obter_usuario(id: u32) -> String {
    format!("Usuário {}", id)
}

// Parâmetros opcionais em query string: ?pagina=2&limite=10
#[get("/produtos?<pagina>&<limite>")]
fn listar_produtos(pagina: Option<u32>, limite: Option<u32>) -> String {
    let pagina = pagina.unwrap_or(1);
    let limite = limite.unwrap_or(20);
    format!("Página {} com até {} produtos", pagina, limite)
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![saudacao, obter_usuario, listar_produtos])
}
```

Ponto central do design do Rocket: **`/usuarios/<id>` com `id: u32` não aceita `/usuarios/abc`.** A requisição inválida é roteada para o próximo handler compatível (ou vira 404/422), sem uma linha de validação escrita por você. Um id negativo, uma string não numérica ou um overflow retornam erro antes do handler rodar — validação de entrada pela assinatura da função, não por `if`s.

Ranking de rotas: quando dois handlers podem atender à mesma requisição, o Rocket usa a ordem declarada em `routes![]` como prioridade e o *ranking* automático de especificidade (rotas com menos parâmetros dinâmicos ganham de rotas com mais). Na prática, declare a rota mais específica primeiro e teste conflitos com o framework de testes.

### JSON de entrada e saída

Com a feature `json`, o Rocket integra [Serde](/ecossistema/serde/) de ponta a ponta:

```rust
use rocket::serde::{Deserialize, Serialize, json::Json};

#[derive(Deserialize)]
#[serde(crate = "rocket::serde")]
struct NovoProduto<'r> {
    nome: &'r str,
    preco_em_centavos: u64,
}

#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
struct Produto {
    id: u32,
    nome: String,
    preco_em_centavos: u64,
}

#[post("/produtos", data = "<novo>")]
fn criar_produto(novo: Json<NovoProduto>) -> Json<Produto> {
    let produto = Produto {
        id: 1,
        nome: novo.nome.to_string(),
        preco_em_centavos: novo.preco_em_centavos,
    };
    Json(produto)
}
```

O argumento `data = "<novo>"` liga o corpo da requisição ao extractor `Json<T>`: um corpo malformado ou que não casa com o schema devolve **422 Unprocessable Entity** automaticamente. Devolver `Json(produto)` serializa a resposta com o `Content-Type: application/json`.

Para respostas com controle de status, use `Result` com um responder de erro:

```rust
use rocket::response::status;
use rocket::http::Status;

#[get("/produtos/<id>")]
fn obter_produto(id: u32) -> Result<Json<Produto>, status::NotFound<String>> {
    if id == 1 {
        Ok(Json(Produto { id, nome: "Café".into(), preco_em_centavos: 1500 }))
    } else {
        Err(status::NotFound(format!("Produto {} não encontrado", id)))
    }
}
```

### Managed state: compartilhando estado entre handlers

Estado global — pools de banco, clientes HTTP, configuração — entra no builder com `.manage()` e chega nos handlers como `&State<T>`:

```rust
use rocket::State;
use std::sync::atomic::{AtomicUsize, Ordering};

struct Contador {
    visitas: AtomicUsize,
}

#[get("/visitas")]
fn visitas(contador: &State<Contador>) -> String {
    let atual = contador.visitas.fetch_add(1, Ordering::SeqCst) + 1;
    format!("Esta página foi vista {} vezes", atual)
}

#[launch]
fn rocket() -> _ {
    rocket::build()
        .manage(Contador { visitas: AtomicUsize::new(0) })
        .mount("/", routes![visitas])
}
```

Regras práticas do managed state:

- O Rocket exige que o tipo seja `Send + Sync + 'static`; pools como o do [SQLx](/ecossistema/sqlx/) já satisfazem isso.
- Um único valor por tipo: para dois pools do mesmo tipo, encapsule em uma struct.
- O `State` é uma referência barata — não clone o conteúdo só para passar adiante.

### Formulários, cookies e sessões

O Rocket nasceu com suporte de primeira classe a HTML forms, o que o torna forte em aplicações web tradicionais, não só em APIs:

```rust
use rocket::form::Form;

#[derive(FromForm)]
struct Login<'r> {
    usuario: &'r str,
    senha: &'r str,
}

#[post("/login", data = "<form>")]
fn login(form: Form<Login>) -> String {
    format!("Usuário {} autenticado", form.usuario)
}
```

Cookies vêm tipados com `&CookieJar` e o Rocket oferece cookies privados (assinados) para sessões leves:

```rust
use rocket::http::{Cookie, CookieJar};

#[post("/sessao")]
fn criar_sessao(jar: &CookieJar<'_>) -> &'static str {
    jar.add_private(Cookie::new("usuario", "maria"));
    "Sessão criada"
}

#[get("/sessao")]
fn ler_sessao(jar: &CookieJar<'_>) -> String {
    match jar.get_private("usuario") {
        Some(cookie) => format!("Sessão de {}", cookie.value()),
        None => "Sem sessão".into(),
    }
}
```

## Recursos Avançados

### Request guards: autenticação como tipo

O mecanismo mais elegante do Rocket é o guard: um tipo que decide **se a requisição chega ao handler**. Autenticação vira parte da assinatura:

```rust
use rocket::request::{self, Request, FromRequest};
use rocket::outcome::Outcome;

struct UsuarioAutenticado {
    nome: String,
}

#[rocket::async_trait]
impl<'r> FromRequest<'r> for UsuarioAutenticado {
    type Error = ();

    async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
        match req.headers().get_one("Authorization") {
            Some(token) if token == "Bearer token-secreto" => {
                Outcome::Success(UsuarioAutenticado { nome: "maria".into() })
            }
            _ => Outcome::Error((rocket::http::Status::Unauthorized, ())),
        }
    }
}

#[get("/painel")]
fn painel(usuario: UsuarioAutenticado) -> String {
    format!("Bem-vinda ao painel, {}", usuario.nome)
}
```

Sem token válido, `/painel` responde **401 Unauthorized** sem o handler executar. O mesmo mecanismo serve para rate limits por IP, injeção de correlação de tracing, idioma preferido e qualquer decisão pré-handler. Guards compõem: um handler pode exigir `UsuarioAutenticado` e `Admin` como argumentos consecutivos.

### Fairings: middleware explícito

Fairings são hooks globais anexados com `.attach()`. Um fairing de log simples:

```rust
use rocket::{Request, Data, fairing::{Fairing, Kind, Info}};
use rocket::futures;

struct LogRequisicoes;

#[rocket::async_trait]
impl Fairing for LogRequisicoes {
    fn info(&self) -> Info {
        Info { name: "Log de requisições", kind: Kind::Request }
    }

    async fn on_request(&self, req: &mut Request<'_>, _data: &mut Data<'_>) {
        println!("{} {}", req.method(), req.uri());
    }
}

#[launch]
fn rocket() -> _ {
    rocket::build()
        .attach(LogRequisicoes)
        .mount("/", routes![raiz])
}
```

Hooks disponíveis: `on_request` (antes do roteamento), `on_response` (antes de enviar a resposta — ideal para cabeçalhos de segurança), `on_launch`, `on_shutdown` e `on_ignite`. O Rocket já traz fairings prontos, como o de coleta de métricas. A diferença cultural para o ecossistema [Tower](/ecossistema/tower/): fairings são globais e explícitos; layers Tower envolvem serviços individualmente e são reutilizáveis entre frameworks.

### Banco de dados com rocket_db_pools

A crate oficial `rocket_db_pools` integra pools de conexão ao managed state, com suporte a PostgreSQL via [SQLx](/ecossistema/sqlx/), SQLite, MySQL e MongoDb:

```toml
[dependencies]
rocket = { version = "0.5", features = ["json"] }
rocket_db_pools = { version = "0.2", features = ["sqlx_postgres"] }
sqlx = { version = "0.8", default-features = false, features = ["postgres", "macros", "runtime-tokio"] }
```

```rust
use rocket_db_pools::{Database, Connection};
use rocket::{Build, Rocket};

#[derive(Database)]
#[database("meubanco")]
struct MeuBanco(sqlx::PgPool);

#[get("/contagem")]
async fn contagem(db: &MeuBanco) -> Result<String, String> {
    let row: (i64,) = sqlx::query_as("SELECT COUNT(*) FROM produtos")
        .fetch_one(&**db)
        .await
        .map_err(|e| e.to_string())?;
    Ok(format!("{} produtos", row.0))
}

#[rocket::launch]
fn rocket() -> _ {
    rocket::build()
        .attach(MeuBanco::init())
        .mount("/", rocket::routes![contagem])
}
```

A string `meubanco` aponta para a configuração em `Rocket.toml`:

```toml
[default.databases.meubanco]
url = "postgres://app:senha@localhost/app"
```

O pool é criado, gerenciado e encerrado junto com o ciclo de vida da aplicação. Para queries complexas e migrações, o fluxo do [tutorial de SQLx](/blog/sqlx-migrations-rust-postgresql-ci-deploy-2026/) aplica igualmente em serviços Rocket.

### Templates dinâmicos com Tera

Para páginas HTML renderizadas no servidor, `rocket_dyn_templates` traz o motor Tera embutido:

```rust
use rocket_dyn_templates::{Template, context};

#[get("/pagina")]
fn pagina() -> Template {
    Template::render("pagina", context! {
        titulo: "Início",
        itens: vec!["Café", "Chimarrão", "Pão de queijo"],
    })
}
```

Com `fairings` e templates, o Rocket cobre o ciclo completo de uma aplicação web monolítica em uma única stack — um perfil diferente do backend de API puro.

### Testes

O Rocket traz um framework de testes local que dispara requisições reais contra a aplicação em memória:

```rust
#[cfg(test)]
mod testes {
    use super::*;
    use rocket::local::asynchronous::Client;
    use rocket::uri;

    #[rocket::async_test]
    async fn raiz_retorna_ola() {
        let client = Client::tracked(rocket()).await.expect("cliente válido");
        let resposta = client.get(uri!(raiz)).dispatch().await;
        assert_eq!(resposta.into_string().await, Some("Olá, mundo!".into()));
    }
}
```

`Client::tracked` mantém cookies entre requisições — perfeito para testar sessões e autenticação. A macro `uri!` gera a URI a partir da rota declarada, então renomear caminhos quebra o teste em tempo de compilação, não em produção.

### Configuração por ambiente

Todo o comportamento de runtime vem do `Rocket.toml` (perfis `default`, `debug`, `release`) ou de variáveis de ambiente `ROCKET_`:

```toml
[default]
address = "0.0.0.0"
port = 8000
workers = 8

[release]
log_level = "warn"
ident = "minha-api"
```

Segredos não vão para o arquivo versionado: use `ROCKET_...` no ambiente do deploy ou leia via crate de configuração como a [Config](/ecossistema/config/), integrando com o managed state.

### Deploy em produção

O caminho de produção para um binário Rocket segue o padrão do ecossistema:

```dockerfile
FROM rust:1 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim
COPY --from=builder /app/target/release/minha-api-rocket /usr/local/bin/app
USER 1000
CMD ["./app"]
```

No VPS, systemd ou Docker Compose gerenciam o processo, com `ROCKET_ADDRESS=0.0.0.0` e `ROCKET_PORT` definidos no ambiente. O guia de [deploy de Rust em VPS com Docker e systemd](/blog/deploy-rust-vps-docker-systemd-2026/) cobre o fluxo completo, e o de [builds Docker otimizados](/blog/rust-docker-builds-otimizados-producao-2026/) mostra como encurtar o build multi-stage.

## Boas Práticas

1. **Valide pela assinatura.** Prefira parâmetros tipados (`id: u32`, guards de query, `FromForm`) a validar strings dentro do handler. Se a validação cabe num tipo, o Rocket faz antes do handler rodar.
2. **Um tipo por estado, um estado por aplicação.** Estruture todo o estado compartilhado numa única struct de aplicação e registre-a uma vez com `.manage()`.
3. **Autenticação como guard, não como if.** Transforme políticas de acesso em tipos que implementam `FromRequest` e componha guards em vez de repetir checagens.
4. **Erros como tipos.** Modele erros com [Thiserror](/ecossistema/anyhow-thiserror/) e implemente `Responder` no tipo de erro da aplicação — handlers devolvem `Result<Resposta, ErroApp>` sem `unwrap`.
5. **Teste com `Client::tracked` e `uri!`.** O custo de escrever testes de integração no Rocket é próximo de zero; use-o para travar contratos de rota.
6. **Observe com fairing + [Tracing](/ecossistema/tracing/).** Um fairing de `on_request`/`on_response` abre spans por requisição e integra com o resto da stack de observabilidade.
7. **Não reinvente módulos oficiais.** Antes de escolher crates de comunidade para templates, cookies, DB pools e WebSockets, verifique a família `rocket_*` — a integração com o ciclo de vida da aplicação já vem pronta.

## Exemplos Práticos

### API REST completa

```rust
#[macro_use] extern crate rocket;

use rocket::serde::{Serialize, json::Json};
use rocket::response::status;
use rocket::{State,serde::Deserialize};
use std::sync::Mutex;

#[derive(Serialize, Deserialize, Clone)]
#[serde(crate = "rocket::serde")]
struct Tarefa {
    id: u32,
    titulo: String,
    feita: bool,
}

struct Banco {
    tarefas: Mutex<Vec<Tarefa>>,
    proximo_id: std::sync::atomic::AtomicU32,
}

#[get("/tarefas")]
fn listar(banco: &State<Banco>) -> Json<Vec<Tarefa>> {
    let tarefas = banco.tarefas.lock().unwrap().clone();
    Json(tarefas)
}

#[post("/tarefas", data = "<nova>")]
fn criar(
    nova: Json<std::collections::HashMap<String, String>>,
    banco: &State<Banco>,
) -> status::Created<Json<Tarefa>> {
    use std::sync::atomic::Ordering;
    let id = banco.proximo_id.fetch_add(1, Ordering::SeqCst) + 1;
    let tarefa = Tarefa {
        id,
        titulo: nova.get("titulo").cloned().unwrap_or_default(),
        feita: false,
    };
    banco.tarefas.lock().unwrap().push(tarefa.clone());
    status::Created::new("/tarefas").body(Json(tarefa))
}

#[delete("/tarefas/<id>")]
fn remover(id: u32, banco: &State<Banco>) -> status::NoContent {
    banco.tarefas.lock().unwrap().retain(|t| t.id != id);
    status::NoContent
}

#[launch]
fn rocket() -> _ {
    rocket::build()
        .manage(Banco {
            tarefas: Mutex::new(vec![
                Tarefa { id: 1, titulo: "Estudar ownership".into(), feita: false },
            ]),
            proximo_id: std::sync::atomic::AtomicU32::new(1),
        })
        .mount("/", routes![listar, criar, remover])
}
```

## Comparação com Alternativas

| Característica | Rocket | [Axum](/ecossistema/axum/) | [Actix Web](/ecossistema/actix-web/) |
|---|---|---|---|
| **Performance** | Boa | Excelente | Excelente (top benchmarks) |
| **Maturidade** | Madura (desde 2016) | Jovem (desde 2021) | Muito madura (desde 2017) |
| **API style** | Macros de atributo, declarativa | Funções + composição | Macros + config |
| **Middleware** | Fairings | Tower (padrão do ecossistema) | Próprio (Transform) |
| **Estado** | Managed state (`&State<T>`) | State extractor | `web::Data` (Arc) |
| **Validação de entrada** | Tipos na assinatura | Extractors | Extractors |
| **Formulários e sessões** | Oficiais, integrados | Via crates | Via crates |
| **Templates** | Tera integrado (`rocket_dyn_templates`) | Tera, Askama | Tera, Askama |
| **Testes** | Framework integrado com cookies | Via `tower::ServiceExt` | Framework integrado |
| **Ecossistema** | Moderado | Grande e crescendo | Grande |

O Rocket se destaca por:

- **Ergonomia máxima**: menos código por rota do que qualquer concorrente direto
- **Validação por tipos na assinatura**: erros de entrada respondidos antes do handler
- **Batteries included**: formulários, cookies privados, templates e DB pools oficiais
- **Framework de testes integrado** com `Client::tracked` para sessões
- **Ótimo para aplicações full-stack** monolíticas renderizando HTML no servidor

Quando preferir as alternativas: [Axum](/ecossistema/axum/) quando o time já vive no mundo Tower/Tokio ou quer a maior comunidade; [Actix Web](/ecossistema/actix-web/) quando o teto de throughput importa. Os detalhes estão no comparativo [Axum vs Actix](/artigos/axum-vs-actix/) e na visão geral de [Rust para web](/artigos/rust-para-web/).

## Conclusão

Rocket é o framework web em Rust que mais reduz o código entre a ideia e a primeira API funcionando: rotas declarativas, entrada validada por tipos, estado gerenciado, fairings explícitos e módulos oficiais para o resto. Para aplicações full-stack com HTML, formulários e sessões, é a stack mais completa em uma única família de crates.

Pontos-chave para lembrar:

- **`#[get]`, `#[post]`** e companhia declaram rota e handler juntos
- **Parâmetros tipados** na assinatura validam path e query antes do handler
- **`.manage()` + `&State<T>`** para pools, clientes e configuração
- **Request guards** transformam autenticação em tipo, com 401 automático
- **Fairings** com `.attach()` para middleware global de log, headers e métricas
- **`rocket_dyn_templates`** e **`rocket_db_pools`** para HTML e banco sem caça a crates
- **`Client::tracked` + `uri!`** para testes de integração baratos

Para aprofundar, consulte a [documentação oficial do Rocket](https://rocket.rs/guide/v0.5/) e os [exemplos no GitHub](https://github.com/rwf2/Rocket/tree/master/examples).

Para comparar antes de decidir, veja os guias de [Axum](/ecossistema/axum/), [Actix Web](/ecossistema/actix-web/) e o [comparativo entre os dois](/artigos/axum-vs-actix/), ou siga o [tutorial de API REST com Axum](/tutoriais/api-rest-axum/) quando quiser a experiência no estilo Tower.

## Perguntas frequentes sobre Rocket

### O que é o Rocket?

É um framework web em Rust focado em ergonomia, com rotas via macros de atributo, validação de entrada por tipos, managed state, fairings, templates Tera e framework de testes integrado — assíncrono sobre o [Tokio](/ecossistema/tokio/) desde a versão 0.5.

### Como instalar o Rocket?

`cargo add rocket` (com a feature `json` para APIs) via [Cargo](/ecossistema/cargo/), mais `#[macro_use] extern crate rocket;` no `main.rs` para habilitar as macros de rota.

### Rocket ou Axum: qual escolher em 2026?

Rocket quando você quer convenções prontas e uma stack completa para aplicações web tradicionais; [Axum](/ecossistema/axum/) quando o valor está na integração com [Tower](/ecossistema/tower/) e na maior comunidade do ecossistema. O comparativo entre Axum e Actix Web está em [Axum vs Actix](/artigos/axum-vs-actix/).

### Como compartilhar estado entre handlers no Rocket?

Com managed state: `.manage(valor)` no builder e `&State<T>` nos handlers. O tipo precisa ser `Send + Sync`, o que pools do [SQLx](/ecossistema/sqlx/) e `Arc<Mutex<T>>` já satisfazem.

### Como autenticar rotas no Rocket?

Implemente `FromRequest` para um tipo de usuário autenticado (lendo header, cookie privado ou token JWT) e receba-o como argumento nos handlers protegidos — o guard retorna 401 antes de o handler rodar. Para o padrão com Axum, veja [autenticação JWT com Axum](/blog/autenticacao-jwt-rust-axum-2026/).

### Rocket aparece em vagas no Brasil?

Menos que Axum e Actix Web, mas aparece em serviços internos e startups. O grosso das [vagas de Rust](/vagas/) pede Axum, Actix Web, Tokio e SQLx; conhecer Rocket acelera protótipos e soma como diferencial. Veja a [trilha de carreira backend](/carreira/nicho-web-backend/) e os [salários de Rust no Brasil](/blog/salario-rust-brasil-2026/).
