Introdução ao trabalho com bancos de dados na linguagem Rust
A linguagem Rust está rapidamente ganhando popularidade em programação de sistemas, mas suas capacidades vão muito além de tarefas de baixo nível. Graças ao sistema de tipos rigoroso, segurança de memória e alta performance, Rust se torna uma excelente escolha para criar aplicações server-side confiáveis que trabalham com bancos de dados. Neste artigo, vamos detalhar como conectar e executar operações com dois SGBDs populares: o relacional PostgreSQL e o orientado a documentos MongoDB.
Vamos abordar as principais bibliotecas (crates), como diesel para PostgreSQL e o driver oficial mongodb, além de mostrar exemplos de operações CRUD em Rust puro. O artigo será útil tanto para iniciantes quanto para desenvolvedores experientes que desejam expandir seu stack de tecnologias.
1. Trabalhando com PostgreSQL: a crate Diesel
Diesel é um ORM e construtor de consultas seguro e extensível para Rust. Ele garante a verificação de tipos em tempo de compilação, o que elimina muitos erros de tempo de execução relacionados a consultas SQL. Para começar, é necessário adicionar as dependências no arquivo Cargo.toml.
Instalação e configuração
Adicione as seguintes crates:
[dependencies]diesel = { version = "2.1", features = ["postgres"] }dotenvy = "0.15"serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"tokio = { version = "1.0", features = ["full"] }Instale também a ferramenta de linha de comando Diesel CLI:
cargo install diesel_cli --no-default-features --features postgresCrie um arquivo .env na raiz do projeto com a URL do seu banco de dados:
DATABASE_URL=postgres://username:password@localhost/my_databaseExecute o comando para configurar as migrações:
diesel setupdiesel migration generate create_usersDefinição do schema e do modelo
No arquivo de migração up.sql, escreva o SQL para criar a tabela:
CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR NOT NULL, email VARCHAR NOT NULL UNIQUE, age INTEGER NOT NULL);Em seguida, execute diesel migration run. Depois disso, gere o schema Rust (arquivo src/schema.rs) usando:
diesel print-schema > src/schema.rsAgora vamos definir o modelo e a estrutura para inserção de dados:
// src/models.rsuse diesel::prelude::*;use serde::{Deserialize, Serialize};use crate::schema::users;
#[derive(Queryable, Selectable, Serialize, Deserialize)]#[diesel(table_name = users)]pub struct User { pub id: i32, pub name: String, pub email: String, pub age: i32,}
#[derive(Insertable, Deserialize)]#[diesel(table_name = users)]pub struct NewUser { pub name: String, pub email: String, pub age: i32,}Operações CRUD com PostgreSQL
Vamos considerar as operações principais. Conexão ao banco de dados e criação de um novo usuário:
use diesel::prelude::*;use dotenvy::dotenv;use std::env;
use crate::models::{NewUser, User};use crate::schema::users::dsl::*;
pub fn establish_connection() -> PgConnection { dotenv().ok(); let database_url = env::var("DATABASE_URL") .expect("DATABASE_URL must be set"); PgConnection::establish(&database_url) .expect(&format!("Error connecting to {}", database_url))}
pub fn create_user(conn: &mut PgConnection, name: &str, email: &str, age: i32) -> User { let new_user = NewUser { name: name.to_string(), email: email.to_string(), age, };
diesel::insert_into(users) .values(&new_user) .returning(User::as_returning()) .get_result(conn)```