Trabalho com bancos de dados em Rust: PostgreSQL e MongoDB

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 e bancos de dados são a combinação ideal

Rust é uma linguagem de programação de sistemas moderna que combina o desempenho de C/C++ com a segurança de memória garantida pelo compilador. Ao desenvolver serviços de backend, aplicações web e microsserviços, quase sempre surge a necessidade de interagir com bancos de dados. Neste artigo, vamos detalhar como trabalhar com os dois tipos de BD mais populares: o relacional PostgreSQL e o orientado a documentos MongoDB.

Abordaremos conexão, execução de operações CRUD, transações e agregações com exemplos práticos. Todos os exemplos de código são escritos em Rust usando o runtime assíncrono tokio, o que proporciona desempenho máximo.

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

Para começar, vamos criar um novo projeto e adicionar os crates necessários. Abra o terminal e execute:

cargo new rust_db_example
cd rust_db_example

Adicione as dependências no arquivo Cargo.toml:

[dependencies]
tokio = { version = "1", features = ["full"] }
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres"] }
mongodb = "2.8"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
chrono = { version = "0.4", features = ["serde"] }

Agora a estrutura do projeto está pronta. Usaremos sqlx para PostgreSQL — um driver assíncrono com suporte a consultas compiláveis, e o driver oficial mongodb para trabalhar com MongoDB.

1.1. Conexão ao PostgreSQL via sqlx

Vamos escrever um módulo para trabalhar com PostgreSQL. Crie o arquivo src/postgres.rs:

use sqlx::postgres::PgPoolOptions;
use sqlx::PgPool;
use anyhow::Result;

pub async fn connect_to_postgres() -> Result<PgPool> {
    let database_url = "postgres://user:password@localhost:5432/mydb";
    let pool = PgPoolOptions::new()
        .max_connections(5)
        .connect(database_url)
        .await?;
    println!("✅ Conectado ao PostgreSQL");
    Ok(pool)
}

// Definindo o modelo de usuário
#[derive(Debug, sqlx::FromRow)]
pub struct User {
    pub id: i32,
    pub name: String,
    pub email: String,
    pub created_at: chrono::NaiveDateTime,
}

1.2. Conexão ao MongoDB

Crie o arquivo src/mongodb.rs:

use mongodb::{Client, Collection, Database};
use mongodb::bson::{doc, Document};
use anyhow::Result;

pub async fn connect_to_mongodb() -> Result<(Database, Collection<Document>)> {
    let client = Client::with_uri_str("mongodb://localhost:27017")?;
    let database = client.database("mydb");
    let collection = database.collection::<Document>("users");
    println!("✅ Conectado ao MongoDB");
    Ok((database, collection))
}

2. Operações CRUD no PostgreSQL

Agora vamos implementar as operações básicas: criação, leitura, atualização e exclusão de registros.

2.1. Inserção de dados (CREATE)

pub async fn create_user(pool: &PgPool, name: &str, email: &str) -> Result<User> {
    let user = sqlx::query_as::<_, User>(
        "INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id, name, email, created_at"
    )
    .bind(name)
    .bind(email)
    .fetch_one(pool)
    .await?;
    
    println!("Usuário criado: {:?}", user);
    Ok(user)
}

2.2. Leitura de dados (READ)

pub async fn get_user_by_id(pool: &PgPool, user_id: i32) -> Result<Option<User>> {
    let user = sqlx::query_as::<_, User>(
        "SELECT id, name, email, created_at FROM users WHERE id = $1"
    )
    .bind(user_id)
    .fetch_optional(pool)
    .await?;
    
    match user {
        Some(u) => println!("Usuário encontrado: {:?}", u),
        None => println!("Usuário com id={} não encontrado"                

Blogs

Book Recommendations