Como escrever uma API REST em Rust em 30 minutos: para iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que Rust para API REST?

Rust é uma linguagem de programação de sistemas moderna que combina o desempenho do C++ com a segurança de memória. Nos últimos anos, tornou-se uma escolha popular para criar serviços web de alta carga. Se você já conhece Python e quer experimentar algo novo, Rust será um ótimo passo adiante.

Neste artigo, criaremos uma API REST completa para gerenciar uma lista de tarefas (Todo List) em Rust usando o framework Actix-web. Todo o processo levará no máximo 30 minutos se você seguir as instruções.



1. Preparação do ambiente

Instalação do Rust

Se você ainda não tem o Rust instalado, execute o comando no terminal (Linux/macOS):

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Para Windows, baixe o instalador do site oficial.

Após a instalação, verifique a versão:

rustc --version


Criação do projeto

Vamos criar um novo projeto com o Cargo, o gerenciador de pacotes do Rust:

cargo new rust_todo_apicd rust_todo_api


Adição de dependências

Abra o arquivo Cargo.toml e adicione as seguintes dependências:

[dependencies]actix-web = "4"actix-rt = "2"serde = { version = "1", features = ["derive"] }serde_json = "1"tokio = { version = "1", features = ["full"] }

Salve o arquivo. O Cargo baixará automaticamente todas as bibliotecas na primeira compilação.



2. Criação do modelo de dados e armazenamento

Antes de escrever os endpoints, vamos definir a estrutura de dados. Usaremos um vetor simples em memória (para demonstração).



Modelo de tarefa

Crie o arquivo src/models.rs:

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Clone)]pub struct Task { pub id: u32, pub title: String, pub completed: bool,}


Armazenamento global

Em src/main.rs, adicionaremos o estado global. Para segurança de threads, usaremos Mutex:

use std::sync::Mutex;use actix_web::{web, App, HttpServer, HttpResponse, HttpRequest, Responder};use models::Task;

mod models;

struct AppState { tasks: Mutex<Vec<Task>>, next_id: Mutex<u32>,}


3. Implementação dos endpoints CRUD

Agora vamos escrever os principais manipuladores. Todos eles receberão o estado da aplicação através de web::Data.



GET /tasks — obter todas as tarefas

async fn get_tasks(data: web::Data<AppState>) -> impl Responder {    let tasks = data.tasks.lock().unwrap();    HttpResponse::Ok().json(tasks.clone())}


POST /tasks — criar uma nova tarefa

async fn create_task(data: web::Data<AppState>, body: web::Json<Task>) -> impl Responder {    let mut tasks = data.tasks.lock().unwrap();    let mut next_id = data.next_id.lock().unwrap();    let new_task = Task {        id: *next_id,        title: body.title.clone(),        completed: false,    };    tasks.push(new_task.clone());    *next_id += 1;    HttpResponse::Created().json(new_task)}


GET /tasks/{id} — obter tarefa por ID

async fn get_task(data: web::Data<AppState>, path: web::Path<u32>) -> impl Responder {    let id = path.into_inner();    let tasks = data.tasks.lock().unwrap();    match tasks.iter().find(|t| t.id == id) {        Some(task) => HttpResponse::Ok().json(task),        None => HttpResponse::NotFound().json("Task not found"),    }}


DELETE /tasks/{id} — excluir tarefa

async fn delete_task(data: web::Data<AppState>, path: web::Path<u32>) -> impl Responder {    let id = path.into_inner();    l                

Blogs

Book Recommendations