Microsserviços em Rust: arquitetura e prática 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 microsserviços?

A arquitetura de microsserviços já se tornou padrão para construir sistemas distribuídos escaláveis. Geralmente, escolhe-se Go, Java ou Node.js para sua implementação. No entanto, nos últimos anos, Rust — uma linguagem de programação de sistemas que combina o desempenho do C++ com a segurança de memória — tem atraído cada vez mais atenção. Neste artigo em pythonlib.ru, vamos analisar como criar microsserviços em Rust, quais bibliotecas usar e como organizar a arquitetura.

Rust é ideal para microsserviços graças a:

  • Ausência de garbage collector (baixa latência e consumo de memória previsível);
  • Trabalho seguro com memória em tempo de compilação;
  • Excelente suporte a assincronicidade através do ecossistema Tokio;
  • Tamanho pequeno do arquivo binário final (ideal para conteinerização).


Arquitetura de um microsserviço em Rust

Um microsserviço típico em Rust consiste em várias camadas:

  • Servidor HTTP (geralmente baseado em actix-web ou axum);
  • Lógica de negócio (funções puras em Rust);
  • Camada de dados (trabalho com BD via sqlx ou diesel);
  • Runtime assíncrono (Tokio);
  • Serialização (na maioria das vezes serde para JSON).

Vamos considerar a arquitetura básica usando como exemplo um serviço simples de gerenciamento de usuários.



1. Configuração do projeto e dependências

Crie um novo projeto Cargo e adicione as dependências no Cargo.toml:

[package]name = "user-service"version = "0.1.0"edition = "2021"

[dependencies]actix-web = "4"serde = { version = "1", features = ["derive"] }serde_json = "1"tokio = { version = "1", features = ["full"] }sqlx = { version = "0.7", features = ["runtime-tokio", "postgres"] }dotenv = "0.15"


2. Criando a estrutura principal do servidor

Vamos definir os modelos de dados e iniciar o servidor HTTP:

use actix_web::{web, App, HttpServer, Responder};use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone)]struct User { id: u32, name: String, email: String,}

// Armazenamento in-memory para exemploasync fn get_users() -> impl Responder { let users = vec![ User { id: 1, name: "Alice".into(), email: "alice@example.com".into() }, User { id: 2, name: "Bob".into(), email: "bob@example.com".into() }, ]; web::Json(users)}

#[actix_web::main]async fn main() -> std::io::Result<()> { println!("Starting user-service on http://127.0.0.1:8080");

HttpServer::new(|| { App::new() .route("/users", web::get().to(get_users)) }) .bind("127.0.0.1:8080")? .run() .await}

Este é um microsserviço mínimo. Observe: #[actix_web::main] é uma macro que inicia o runtime assíncrono Tokio.



3. Trabalho assíncrono com banco de dados

Um microsserviço real deve persistir dados. Usaremos sqlx para PostgreSQL. Crie um arquivo .env com a URL de conexão:

DATABASE_URL=postgres://user:password@localhost/users_db

Agora vamos escrever uma função para obter usuários do BD:

use sqlx::PgPool;

async fn get_users_from_db(pool: web::Data<PgPool>) -> impl Responder { // Executa a consulta SQL e mapeia o resultado para a estrutura User let users: Vec<User> = sqlx::query_as::<_, User>("SELECT id, name, email FROM users") .fetch_all(pool.get_ref()) .await .unwrap_or_default();

web::Json(users)}

#[actix_web::main]async fn main() -> std::io::Result<()> { dotenv::dotenv().ok(); let database_url = std::env::va

Blogs

Book Recommendations