DevPath · Aprenda a programar ESPTEN

Dados, ORMs e arquitetura em camadas

Acesso a dados: drivers e ORMs

Falar com o banco de dados

Um servidor quase nunca guarda os dados na memória: ele os persiste em um banco de dados (PostgreSQL, MySQL, SQLite...). Para falar com ele, o Node usa um driver: uma biblioteca que abre conexões e envia consultas SQL.

Pools de conexão

Abrir uma conexão é caro. Por isso não se abre uma por requisição, mas sim se mantém um pool (um conjunto de conexões reutilizáveis). Cada consulta pega emprestada uma conexão do pool e a devolve ao terminar:

import { Pool } from "pg";
const pool = new Pool({ connectionString: process.env.DATABASE_URL });

Consultas assíncronas

Falar com o banco de dados é uma operação de E/S: leva tempo e não deve bloquear a thread. Por isso as consultas são assíncronas e são aguardadas com async/await:

async function buscarUsuario(id) {
  const { rows } = await pool.query(
    "SELECT * FROM usuarios WHERE id = $1",
    [id]
  );
  return rows[0];
}

Repare em $1 e no array [id]: são parâmetros. Nunca concatene valores no SQL (risco de injeção SQL); passe-os como parâmetros.

ORMs

Escrever SQL na mão é flexível, mas verboso. Um ORM (Object-Relational Mapper) traduz entre tabelas e objetos da sua linguagem. Os mais usados no Node são Prisma, Sequelize e TypeORM. Eles trazem três ideias:

// Estilo Prisma (conceitual)
const usuario = await prisma.usuario.findUnique({ where: { id } });
const novo = await prisma.usuario.create({ data: { email } });

O ORM continua sendo assíncrono por baixo: tudo devolve Promise. Um ORM é comodidade e segurança de tipos; para consultas muito específicas você sempre pode descer ao SQL do driver.

Coloque isto em prática

O DevPath é um curso prático: aqui você lê a teoria; no app você a coloca em prática com exercícios que rodam de verdade, offline.

Comece grátis no app →
O padrão Repositório →