Rust e API: de REST a gRPC — escrevendo rápido e com segurança

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

Por que Rust é o candidato ideal para trabalhar com API?

\n\n

Se você ainda pensa que Rust é apenas para programação de sistemas e substituição do C++, está muito atrasado em relação à realidade. Rust invadiu com confiança o mundo do desenvolvimento web e dos serviços backend. E não apenas invadiu, mas ocupou um nicho onde são importantes velocidade, confiabilidade e segurança de memória.

\n\n

Mas sejamos honestos: trabalhar com API em Rust não é apenas "pegar uma biblioteca pronta e esquecer". É uma arte de equilíbrio entre o poder da linguagem e a facilidade de desenvolvimento. Neste artigo, vamos analisar três abordagens principais: REST, GraphQL e gRPC. Cada uma é boa à sua maneira, e a escolha depende da sua tarefa. Vamos nessa!

\n\n

REST em Rust: o clássico que funciona

\n\n

REST continua sendo o estilo de API mais popular. É simples, intuitivo e suportado por praticamente tudo. Para Rust, existem vários frameworks excelentes, mas o rei aqui é o actix-web. Ele é rápido, assíncrono e possui um ótimo ecossistema.

\n\n

Escrevendo um serviço REST simples com actix-web

\n\n

Vamos criar um minisserviço para gerenciar uma lista de tarefas (todo). Precisaremos de actix-web, serde para serialização e tokio como runtime assíncrono.

\n\n
// Cargo.toml\n// [dependencies]\n// actix-web = "4"\n// serde = { version = "1", features = ["derive"] }\n// serde_json = "1"\n// tokio = { version = "1", features = ["full"] }\n\nuse actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};\nuse serde::{Deserialize, Serialize};\nuse std::sync::Mutex;\n\n#[derive(Serialize, Deserialize, Clone)]\nstruct Task {\n    id: u32,\n    title: String,\n    completed: bool,\n}\n\nstruct AppState {\n    tasks: Mutex<Vec<Task>>,\n}\n\n#[get("/tasks")]\nasync fn get_tasks(data: web::Data<AppState>) -> impl Responder {\n    let tasks = data.tasks.lock().unwrap();\n    HttpResponse::Ok().json(tasks.clone())\n}\n\n#[post("/tasks")]\nasync fn create_task(data: web::Data<AppState>, body: web::Json<Task>) -> impl Responder {\n    let mut tasks = data.tasks.lock().unwrap();\n    let new_id = tasks.len() as u32 + 1;\n    let task = Task {\n        id: new_id,\n        title: body.title.clone(),\n        completed: false,\n    };\n    tasks.push(task.clone());\n    HttpResponse::Created().json(task)\n}\n\n#[actix_web::main]\nasync fn main() -> std::io::Result<()> {\n    let state = web::Data::new(AppState {\n        tasks: Mutex::new(vec![]),\n    });\n\n    HttpServer::new(move || {\n        App::new()\n            .app_data(state.clone())\n            .service(get_tasks)\n            .service(create_task)\n    })\n    .bind("127.0.0.1:8080")?\n    .run()\n    .await\n}\n
\n\n

A beleza deste código é que ele é seguro em termos de memória e não requer um coletor de lixo. O actix-web processa milhares de requisições por segundo em uma única thread, usando mecanismos assíncronos do Rust. Tente executá-lo — você ficará surpreso com o quão rápido ele é, mesmo em hardware modesto.

\n\n

Quando o REST não é a melhor escolha?

\n\n

O REST é excelente para operações CRUD, mas se você precisar consultar dados de forma flexível (por exemplo, recursos aninhados), o REST começa a exigir muitos endpoints. É aí que entra o GraphQL.

\n\n

GraphQL em Rust: flexibilidade sem dor

\n\n

O GraphQL permite que o cliente solicite exatamente os dados de que precisa. Para Rust, a melhor escolha é o async-graphql. Ele se integra perfeitamente com o actix-web e fornece uma DSL poderosa para descrever esquemas.

\n\n

Exemplo: API para uma biblioteca de livros

\n\n

Suponha que queremos dar aos clientes a capacidade de consultar livros e autores. Com GraphQL, isso é feito com um único esquema.

\n\n
// Cargo.toml\n// [dependencies]\n// async-graphql = "7"\n// async-graphql-actix-web = "7"\n// actix-web = "4"\n// serde = { version = "1", features = ["derive"] }\n\nuse async_graphql::{Context, EmptyMutatio                

Blogs

Book Recommendations