0Pricing
Learn Rust Coding · Aula

Configuração do projeto

Estruture a API

Configuração do projeto é uma aula grátis de Learn Rust Coding no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Learn Rust Coding, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Learn Rust Coding inclui 4 aulas no total.

Criando uma API REST em Rust

Neste curso, você criará uma pequena API REST em Rust. Usaremos o framework web Axum, criado sobre Tokio (ambiente de execução assíncrono) e Tower (middleware). Ele é ergonômico, seguro em relação aos tipos e amplamente usado em produção.

Esta primeira lição configura a estrutura do projeto para que as lições posteriores possam adicionar rotas, modelos, um banco de dados e testes.

Criando o projeto

Comece com Cargo. Um projeto binário fornece um ponto de entrada src/main.rs:

  • cargo new rest_api cria a pasta.
  • cd rest_api entra nela.
  • cargo run compila e executa.

Estes são comandos de shell e do cargo, não trechos executáveis de Rust.

// terminal
// cargo new rest_api
// cd rest_api
// cargo run

Adicionando dependências

Uma API Axum precisa de alguns crates em Cargo.toml:

  • axum para roteamento e manipuladores.
  • tokio para o ambiente de execução assíncrono.
  • serde para serialização JSON.
// Cargo.toml
// [dependencies]
// axum = "0.7"
// tokio = { version = "1", features = ["full"] }
// serde = { version = "1", features = ["derive"] }
// serde_json = "1"

O ambiente de execução assíncrono

Servidores web lidam simultaneamente com muitas conexões, então o Axum é assíncrono. O atributo #[tokio::main] transforma um main assíncrono em um ponto de entrada real ao iniciar o ambiente de execução do Tokio. Cada manipulador pode usar .await para E/S não bloqueante.

// src/main.rs
use tokio;

#[tokio::main]
async fn main() {
    println!("runtime started");
}

Um servidor mínimo

O menor aplicativo Axum cria um Router, associa um receptor TCP e atende. Uma única rota mapeia GET / para um manipulador que retorna uma string. Os manipuladores são apenas funções assíncronas que retornam algo que implementa IntoResponse.

use axum::{routing::get, Router};

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(root));
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn root() -> &'static str {
    "Hello, API!"
}

Como funciona o roteamento

Um Router associa um caminho e um método HTTP a um manipulador. Encadeie chamadas .route(path, method(handler)) para registrar endpoints. Auxiliares de método como get, post, put e delete vêm de axum::routing. Você pode combinar métodos no mesmo caminho.

use axum::{routing::{get, post}, Router};

async fn list() -> &'static str { "list" }
async fn create() -> &'static str { "created" }

fn build_router() -> Router {
    Router::new()
        .route("/items", get(list).post(create))
        .route("/health", get(|| async { "ok" }))
}

Organização de módulos recomendada

À medida que a API cresce, divida o código em módulos em vez de manter um único main.rs enorme:

  • main.rs — inicialização e conexão do servidor.
  • routes.rs — definição do roteador.
  • handlers.rs — manipuladores de requisições.
  • models.rs — estruturas de dados.

Essa separação mantém cada arquivo focado e fácil de testar.

// src/main.rs
mod routes;
mod handlers;
mod models;

#[tokio::main]
async fn main() {
    let app = routes::build();
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Estado compartilhado da aplicação

A maioria das APIs precisa de estado compartilhado, como um conjunto de conexões com o banco de dados ou um armazenamento em memória. O Axum o mantém com .with_state(state) no roteador. Os manipuladores o recebem por meio do extrator State. O estado precisa ser Clone; envolva os dados mutáveis em Arc e um bloqueio.

use axum::{routing::get, Router, extract::State};
use std::sync::{Arc, Mutex};

type Db = Arc<Mutex<Vec<String>>>;

async fn count(State(db): State<Db>) -> String {
    let n = db.lock().unwrap().len();
    format!("{} items", n)
}

fn build(db: Db) -> Router {
    Router::new().route("/count", get(count)).with_state(db)
}

Retornando JSON

Para enviar JSON, envolva um valor serializável em axum::Json. Ao derivar Serialize com serde em suas estruturas, o Axum define automaticamente o tipo de conteúdo e o corpo corretos.

use axum::Json;
use serde::Serialize;

#[derive(Serialize)]
struct Status {
    service: String,
    healthy: bool,
}

async fn health() -> Json<Status> {
    Json(Status { service: "api".into(), healthy: true })
}

Configuração e portas

Definir a porta diretamente é aceitável em demonstrações, mas serviços reais leem a configuração do ambiente. Use std::env::var com um valor padrão. Isso permite alterar o endereço de vinculação sem recompilar e facilita o uso com contêineres.

use std::env;

async fn main_inner() {
    let port = env::var("PORT").unwrap_or_else(|_| "3000".to_string());
    let addr = format!("0.0.0.0:{}", port);
    println!("binding to {}", addr);
    // bind and serve with addr ...
}

Reunindo a configuração

Uma inicialização completa conecta tudo: constrói o roteador com rotas e estado compartilhado, lê a porta, vincula um listener e inicia o serviço. Com essa estrutura básica pronta, as próximas lições adicionarão endpoints reais, modelos e persistência.

use axum::{routing::get, Router};
use std::sync::{Arc, Mutex};

#[tokio::main]
async fn main() {
    let db = Arc::new(Mutex::new(Vec::<String>::new()));
    let app = Router::new()
        .route("/health", get(|| async { "ok" }))
        .with_state(db);
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Verificação rápida

Teste sua compreensão da configuração do projeto.

Recapitulação

Você configurou um projeto de API REST em Rust:

  • Use cargo new e adicione axum, tokio e serde.
  • #[tokio::main] fornece o ambiente de execução assíncrono.
  • Um Router associa caminhos e métodos a manipuladores assíncronos.
  • Compartilhe dados com .with_state e o extrator State.
  • Divida o código em módulos de rotas, manipuladores e modelos; leia a porta do ambiente.

Perguntas Frequentes

A aula “Configuração do projeto” é grátis?

Sim — o texto completo de “Configuração do projeto” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Learn Rust Coding, atualize para CoddyKit PRO. O curso de Learn Rust Coding inclui 4 aulas no total.

O que vou aprender em “Configuração do projeto”?

Estruture a API Você pratica Learn Rust Coding com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Learn Rust Coding?

Nenhuma experiência prévia é necessária. Learn Rust Coding no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Configuração do projeto”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Learn Rust Coding?

Sim. Cada aula de Learn Rust Coding inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Configuração do projeto
  2. Endpoints e modelos
  3. Integração com banco de dados
  4. Teste da API
← Voltar para Learn Rust Coding