Passer au contenu principal

Création d'API avec Drizzle ORM et NestJS : guide complet

Créez des API de type sécurisé avec Drizzle ORM et NestJS. Apprenez la définition de schémas, les migrations, la création de requêtes, les relations, les transactions et les modèles de test pour les applications de production.

E
ECOSIRE Research and Development Team
|5 mars 20266 min de lecture1.2k Mots|

Drizzle ORM est devenu l'ORM TypeScript à la croissance la plus rapide, offrant une syntaxe de type SQL avec une sécurité de type totale et une surcharge d'exécution nulle. Combiné avec NestJS, il crée une pile puissante pour créer des API de production à la fois conviviales pour les développeurs et performantes.

Drizzle ORM est devenu l'ORM TypeScript à la croissance la plus rapide, offrant une syntaxe de type SQL avec une sécurité de type totale et une surcharge d'exécution nulle. Combiné avec NestJS, il crée une pile puissante pour créer des API de production à la fois conviviales pour les développeurs et performantes.

Points clés à retenir

  • Drizzle fournit des requêtes de type SQL avec une inférence TypeScript complète – aucune étape de génération de code
  • L'injection de dépendances NestJS s'intègre parfaitement aux connexions à la base de données Drizzle
  • Le développement basé sur des schémas garantit que les types de base de données et TypeScript restent synchronisés
  • Les commandes Drizzle push et migration gèrent l'évolution du schéma sans temps d'arrêt

Configuration du projet

Installation

Commencez avec un projet NestJS et ajoutez des dépendances Drizzle :

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

Nous recommandons le pilote postgres.js pour ses performances. Pour le regroupement de connexions en production, pensez à PgBouncer ou à des pilotes optimisés sans serveur.

Module de connexion à la base de données

Créez un module de base de données global fournissant l'instance Drizzle via l'injection de dépendances. Définissez un fournisseur DB_TOKEN à l'aide de useFactory qui crée un client postgres à partir de DATABASE_URL et renvoie drizzle(client, \\\\\\\\{schema\\\\\\\\}). Exportez le jeton afin que n'importe quel service puisse l'injecter avec @Inject("DRIZZLE_DB").


Définition du schéma

Définissez des tables de base de données à l'aide des générateurs de tables Drizzle. Chaque table exporte un const créé avec pgTable() contenant des définitions de colonnes utilisant uuid, varchar, timestamp, boolean et d'autres types de colonnes. Les colonnes prennent en charge les valeurs par défaut (defaultRandom, defaultNow), les contraintes (notNull, unique) et les relations.

Définir les relations

Les relations Drizzle fournissent un chargement rapide et sécurisé. Définissez des relations à l'aide de la fonction relations(), en spécifiant un-à-plusieurs avec many() et plusieurs-à-un avec one(). Les colonnes de référence mappent les clés étrangères aux clés primaires de leur table parent.


Création de requêtes

Sélectionner des requêtes

Les requêtes Drizzle se lisent comme du SQL tout en fournissant une inférence de type complète :

  • Sélection simple : db.select().from(users)
  • Filtré : db.select().from(users).where(and(eq(users.role, "admin"), eq(users.isActive, true)))
  • Avec jointures : db.select().from(users).leftJoin(orders, eq(users.id,orders.userId))
  • Chargement de la relation : db.query.users.findMany(\\\\\\\\{ with : {orders: true \\\\\\\\}, limit : 20 })

Insérer, Mettre à jour, Supprimer

// 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));

Transactions

Les transactions Drizzle assurent les opérations atomiques. Appelez db.transaction() avec un rappel asynchrone recevant un objet de transaction (tx). Toutes les requêtes du rappel s'exécutent de manière atomique : en cas d'échec, la transaction entière est annulée.

Les cas d'utilisation courants incluent la création conjointe d'enregistrements parents et enfants, la mise à jour de l'inventaire lors du traitement des commandes et le transfert de fonds entre comptes.


Migration

Push de schéma (développement)

Pendant le développement, poussez les modifications de schéma directement avec Drizzle-Kit Push. Cela compare vos fichiers de schéma à la base de données et applique les modifications. Rapide pour le développement mais non adapté à la production.

Fichiers de migration (Production)

Pour la production, générez des fichiers de migration SQL versionnés avec drizzle-kit generate, puis appliquez-les avec drizzle-kit migrate. Les fichiers de migration peuvent être examinés, testés lors de la préparation et appliqués dans les pipelines CI/CD.


Modèles d'intégration NestJS

Modèle de service

Les services injectent la base de données Drizzle et créent des requêtes avec des filtres dynamiques :

@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);
  }
}

Multilocation

Pour les applications SaaS, chaque requête doit être filtrée par OrganizationId. Créez un service de base ou un middleware qui garantit l'isolation des locataires sur toutes les opérations de base de données. Ne faites jamais confiance aux ID d’organisation fournis par le client : validez par rapport à la session authentifiée.

Requêtes paramétrées

Drizzle utilise des requêtes paramétrées par défaut, empêchant l'injection SQL. N'utilisez jamais sql.raw() avec la saisie de l'utilisateur. Utilisez plutôt le littéral du modèle SQL qui paramétre automatiquement les valeurs interpolées.


Meilleures pratiques en matière de performances

  1. Sélectionnez uniquement les colonnes nécessaires : utilisez .select(\\\\\\\\{ id: users.id, name: users.name \\\\\\\\}) au lieu de sélectionner toutes les colonnes
  2. Utiliser des index : assurez-vous que les colonnes fréquemment filtrées disposent d'index de base de données
  3. Résultats limités : utilisez toujours .limit() sur les requêtes de liste
  4. Insérations par lots : utilisez .values([...array]) pour les insertions groupées au lieu des boucles
  5. Regroupement de connexions : configurez les tailles de pool appropriées pour votre charge de travail
  6. Connexions paresseuses : utilisez un modèle de proxy pour différer la connexion jusqu'à la première requête

Questions fréquemment posées

Q : Comment Drizzle se compare-t-il à Prisma pour NestJS ?

Drizzle est plus orienté SQL et n'a aucune surcharge d'exécution (pas de moteur de requête). Prisma utilise son propre langage de requête et nécessite un client généré. Drizzle a une taille de paquet plus petite et des démarrages à froid plus rapides, tandis que Prisma dispose d'un écosystème plus grand et de plus d'outils.

Q : Drizzle peut-il gérer du SQL brut complexe ?

Oui. Le littéral du modèle SQL prend en charge les requêtes brutes tout en conservant la sécurité paramétrée. Drizzle n'utilise jamais la concaténation de chaînes pour les requêtes, empêchant ainsi l'injection SQL.

Q : Qu'en est-il du regroupement de connexions en production ?

Utilisez PgBouncer externe à l'application ou configurez le pilote postgres.js avec des limites de connexion maximales. Pour les environnements sans serveur, utilisez des pilotes optimisés sans serveur avec pooling intégré.

Q : Comment gérer les modifications de schéma sans temps d'arrêt ?

Générez des fichiers de migration, examinez le SQL, testez en préparation, puis appliquez en production. La plupart des instructions ALTER TABLE dans PostgreSQL s'exécutent sans verrous exclusifs. Évitez les opérations qui nécessitent des réécritures de tables pendant les heures de pointe.


Quelle est la prochaine étape

Drizzle ORM avec NestJS fournit une base performante et sécurisée pour la création d'API de production. L'API de type SQL minimise l'écart d'abstraction tandis que l'inférence TypeScript élimine les erreurs de type d'exécution.

Contactez ECOSIRE pour obtenir de l'aide au développement d'API, ou explorez nos Services d'intégration Odoo pour connecter des API personnalisées à votre ERP.


Publié par ECOSIRE – aider les entreprises à évoluer grâce à des solutions logicielles d'entreprise.

E

Rédigé par

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

Développez votre entreprise avec ECOSIRE

Solutions d'entreprise pour l'ERP, le commerce électronique, l'IA, l'analyse et l'automatisation.