Pular para o conteúdo principal

Construindo APIs com Drizzle ORM e NestJS: guia completo

Crie APIs de tipo seguro com Drizzle ORM e NestJS. Aprenda definição de esquema, migrações, criação de consultas, relações, transações e padrões de teste para aplicativos de produção.

E
ECOSIRE Research and Development Team
|5 de março de 20266 min de leitura1.1k Palavras|

O Drizzle ORM emergiu como o ORM TypeScript de crescimento mais rápido, oferecendo sintaxe semelhante a SQL com segurança total de tipo e zero sobrecarga de tempo de execução.

O Drizzle ORM emergiu como o ORM TypeScript de crescimento mais rápido, oferecendo sintaxe semelhante a SQL com segurança total de tipo e zero sobrecarga de tempo de execução. Combinado com o NestJS, ele cria uma pilha poderosa para a construção de APIs de produção que são amigáveis ​​ao desenvolvedor e de alto desempenho.

Principais conclusões

  • Drizzle fornece consultas semelhantes a SQL com inferência TypeScript completa - sem etapa de geração de código
  • A injeção de dependência NestJS integra-se perfeitamente às conexões de banco de dados Drizzle
  • O desenvolvimento orientado por esquema garante que os tipos de banco de dados e TypeScript permaneçam sincronizados
  • Os comandos Drizzle push e migração lidam com a evolução do esquema sem tempo de inatividade

Configuração do projeto

Instalação

Comece com um projeto NestJS e adicione dependências do Drizzle:

npm install drizzle-orm postgres
npm install -D drizzle-kit @types/pg

Recomendamos o driver postgres.js por seu desempenho. Para pooling de conexões em produção, considere PgBouncer ou drivers otimizados sem servidor.

Módulo de conexão de banco de dados

Crie um módulo de banco de dados global fornecendo a instância do Drizzle por meio de injeção de dependência. Defina um provedor DB_TOKEN usando useFactory que cria um cliente postgres a partir de DATABASE_URL e retorna drizzle(client, \\\\\\\\{ esquema \\\\\\\\}). Exporte o token para que qualquer serviço possa injetá-lo com @Inject("DRIZZLE_DB").


Definição de esquema

Defina tabelas de banco de dados usando construtores de tabelas Drizzle. Cada tabela exporta um const criado com pgTable() contendo definições de coluna usando uuid, varchar, timestamp, boolean e outros tipos de coluna. As colunas suportam padrões (defaultRandom, defaultNow), restrições (notNull, unique) e relações.

Definindo Relações

As relações de garoa fornecem carregamento rápido com segurança de tipo. Defina relações usando a função relações(), especificando um para muitos com muitos() e muitos para um com um(). As colunas de referência mapeiam chaves estrangeiras para as chaves primárias da tabela pai.


Construção de consulta

Selecionar consultas

As consultas Drizzle são lidas como SQL, ao mesmo tempo que fornecem inferência de tipo completa:

  • Seleção simples: db.select().from(users)
  • Filtrado: db.select().from(users).where(and(eq(users.role, "admin"), eq(users.isActive, true)))
  • Com junções: db.select().from(users).leftJoin(orders, eq(users.id,orders.userId))
  • Carregamento de relação: db.query.users.findMany(\\\\\\\\{ com: {ordens: true \\\\\\\\}, limite: 20 })

Inserir, atualizar, excluir

// Insert with returning
const [newUser] = await this.db
  .insert(users)
  .values({ email: "user@example.com", name: "New User" })
  .returning();

// Update
await this.db
  .update(users)
  .set({ role: "admin", updatedAt: new Date() })
  .where(eq(users.id, userId));

// Delete
await this.db.delete(users).where(eq(users.id, userId));

Transações

As transações Drizzle garantem operações atômicas. Chame db.transaction() com um retorno de chamada assíncrono recebendo um objeto de transação (tx). Todas as consultas dentro do retorno de chamada são executadas atomicamente – se alguma falhar, toda a transação será revertida.

Os casos de uso comuns incluem a criação de registros pai e filho juntos, atualização de inventário ao processar pedidos e transferência de fundos entre contas.


Migrações

Esquema Push (Desenvolvimento)

Durante o desenvolvimento, o esquema push muda diretamente com o push drizzle-kit. Isso compara seus arquivos de esquema com o banco de dados e aplica as alterações. Rápido para desenvolvimento, mas não adequado para produção.

Arquivos de migração (produção)

Para produção, gere arquivos de migração SQL versionados com drizzle-kit generate e, em seguida, aplique-os com drizzle-kit migrate. Os arquivos de migração podem ser revisados, testados em preparação e aplicados em pipelines de CI/CD.


Padrões de integração NestJS

Padrão de serviço

Os serviços injetam o banco de dados Drizzle e criam consultas com filtros dinâmicos:

@Injectable()
export class ProductsService {
  constructor(@Inject("DRIZZLE_DB") private db: DrizzleDB) {}

  async findAll(filters: ProductFilters) {
    const conditions = [];
    if (filters.category)
      conditions.push(eq(products.category, filters.category));
    if (filters.minPrice)
      conditions.push(gte(products.price, filters.minPrice));

    return this.db
      .select()
      .from(products)
      .where(conditions.length ? and(...conditions) : undefined)
      .orderBy(desc(products.createdAt))
      .limit(filters.limit || 20)
      .offset(filters.offset || 0);
  }
}

Multilocação

Para aplicativos SaaS, cada consulta deve ser filtrada por OrganizationId. Crie um serviço base ou middleware que garanta o isolamento do locatário em todas as operações de banco de dados. Nunca confie em IDs de organização fornecidos pelo cliente – valide em relação à sessão autenticada.

Consultas parametrizadas

Drizzle usa consultas parametrizadas por padrão, evitando injeção de SQL. Nunca use sql.raw() com entrada do usuário. Em vez disso, use o literal do modelo sql que parametriza automaticamente os valores interpolados.


Práticas recomendadas de desempenho

  1. Selecione apenas as colunas necessárias: Use .select(\\\\\\\\{ id: users.id, name: users.name \\\\\\\\}) em vez de selecionar todas as colunas
  2. Use índices: certifique-se de que as colunas filtradas com frequência tenham índices de banco de dados
  3. Limitar resultados: Sempre use .limit() em consultas de lista
  4. Inserções em lote: Use .values([...array]) para inserções em massa em vez de loops
  5. Pooling de conexões: Configure tamanhos de pool apropriados para sua carga de trabalho
  6. Conexões lentas: use um padrão de proxy para adiar a conexão até a primeira consulta

Perguntas frequentes

P: Como o Drizzle se compara ao Prisma para NestJS?

Drizzle é mais orientado a SQL e não tem sobrecarga de tempo de execução (sem mecanismo de consulta). Prisma usa sua própria linguagem de consulta e requer um cliente gerado. Drizzle tem tamanho de pacote menor e partidas a frio mais rápidas, enquanto Prisma tem um ecossistema maior e mais ferramentas.

P: O Drizzle consegue lidar com SQL bruto complexo?

Sim. O literal do modelo SQL oferece suporte a consultas brutas, mantendo a segurança parametrizada. Drizzle nunca usa concatenação de strings para consultas, evitando injeção de SQL.

P: E quanto ao pool de conexões em produção?

Use PgBouncer externo ao aplicativo ou configure o driver postgres.js com limites máximos de conexão. Para ambientes sem servidor, use drivers otimizados sem servidor com pooling integrado.

P: Como lidamos com alterações de esquema sem tempo de inatividade?

Gere arquivos de migração, revise o SQL, teste na preparação e aplique na produção. A maioria das instruções ALTER TABLE no PostgreSQL são executadas sem bloqueios exclusivos. Evite operações que exijam reescritas de tabelas durante horários de pico.


O que vem a seguir

Drizzle ORM com NestJS fornece uma base de desempenho e segurança de tipo para a construção de APIs de produção. A API semelhante a SQL minimiza a lacuna de abstração enquanto a inferência TypeScript elimina erros de tipo de tempo de execução.

Entre em contato com a ECOSIRE para obter assistência no desenvolvimento de API ou explore nossos serviços de integração Odoo para conectar APIs personalizadas ao seu ERP.


Publicado pela ECOSIRE – ajudando empresas a escalar com soluções de software empresarial.

E

Escrito por

ECOSIRE Team

Technical Writing

The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.

ECOSIRE

Expanda o seu negócio com ECOSIRE

Soluções empresariais em ERP, comércio eletrônico, IA, análise e automação.