SQL brut, Prisma ou Drizzle : choisir une couche de base de données pour la sécurité des types et le contrôle
En quoi SQL brut, Prisma et Drizzle diffèrent en termes de contrôle, de sécurité des types et d’expérience de développement sur PostgreSQL, ainsi qu’une méthode pratique pour choisir l’un d’eux pour une application TypeScript.
Sources: Prisma vs Drizzle vs Raw SQL: What Every Backend Developer Should Understand Before Choosing an ORM
La plupart des travaux côté serveur commencent par obtenir une API qui répond. On configure des routes, on ajoute un ou deux contrôleurs, on intégre un système d’authentification ainsi que du middleware, et pendant un certain temps c’est tout ce qui existe. Puis une question plus difficile se pose : comment l’application doit-elle réellement communiquer avec sa base de données ? Soudain, une multitude de termes apparaissent (SQL brut, drivers, ORM, générateurs de requêtes, Prisma, Drizzle) accompagnés d’opinions tranchées de toutes parts. Certains ingénieurs refusent d’utiliser un ORM. D’autres affirment que Prisma leur a économisé des semaines de travail. Un troisième groupe choisit Drizzle car il maintient le SQL visible plutôt que de le cacher. Les sections suivantes développent ce sujet à partir des principes fondamentaux, de sorte que le choix entre SQL brut, Prisma et Drizzle pour une stack TypeScript et PostgreSQL devient une décision technique liée au contrôle et à la sécurité des types, et non une question de mode.
Comment une requête atteint la base de données
Avant que le nom d’un outil n’ait le moindre sens, il est utile de suivre le parcours d’une requête à travers un backend typique. Quelqu’un visite votre site et clique sur un bouton tel que « Afficher mon profil ». Cette action commence dans le navigateur, traverse votre API, atteint la couche de base de données, puis la base de données elle-même, avant que une réponse ne revienne en sens inverse.
Browser
|
vExpress API |
vDatabase Layer |
vPostgreSQL Database |
vResponse back to the user
C’est à la couche de base de données, située au milieu, que se concentre la confusion. Votre application a besoin d’un mécanisme pour communiquer avec la base de données, et il en existe trois courants : écrire manuellement du SQL brut, utiliser un ORM comme Prisma, ou utiliser un constructeur de requêtes comme Drizzle. Chaque section suivante aborde l’un de ces méthodes à tour de rôle.
Écrire du SQL manuellement
La méthode la plus directe est aussi la plus ancienne : vous écrivez vous-même le SQL. Imaginez une table simples des utilisateurs avec les colonnes habituelles.
users
id
name
email
password
Récupérer un seul utilisateur est alors extrêmement simple.
SELECT *
FROM users
WHERE id = 1;
Puisque la base de données utilise SQL comme langue native, rien n’est traduit lors de l’envoi ou de la réception des données. Avec Node.js et PostgreSQL, le package pg est la méthode habituelle pour envoyer des requêtes directement. On y importe un pool de connexions.
import { Pool } from "pg";
Ensuite, vous configurez le pool à partir d’une variable d’environnement et vous exécutez une requête paramétrée contre celui-ci, en lisant les lignes résultantes.
const pool = new Pool({
connectionString: process.env.DATABASE_URL
});const result = await pool.query(
"SELECT * FROM users WHERE id = $1",
[1]
);console.log(result.rows);
Votre code envoie du SQL, PostgreSQL le exécute, et les lignes reviennent directement sans aucune abstraction intermédiaire. Écrire le SQL vous donne un contrôle total. Les rapports complexes, par exemple, sont exprimés directement, comme en reliant les utilisateurs à leurs commandes et en les regroupant pour compter les commandes de chaque utilisateur.
SELECT
users.name,
COUNT(orders.id)
FROM users
JOIN orders
ON users.id = orders.user_id
GROUP BY users.name;
Pour de telles requêtes analytiques complexes, le SQL manuel est véritablement difficile à surpasser. Le fait de le rédiger vous oblige également à comprendre les jointures, les index, les plans d’exécution et la performance en général, et ces connaissances restent précieuses quel que soit l’outil que vous adopterez par la suite. De plus, il n’y a pas de couche supplémentaire entre votre code et le moteur.
Les inconvénients apparaissent dès que le projet dépasse quelques requêtes. Imaginez une base de code contenant des centaines de requêtes dispersées un peu partout, dont beaucoup ressemblent à cette recherche par e-mail.
const result = await pool.query(
`
SELECT *
FROM users
WHERE email=$1
`,
[email]
);
Supposons maintenant que quelqu’un renomme une colonne, en changeant email en email_address. Toute requête qui utilise cette colonne cesse de fonctionner silencieusement. La base de données enregistre immédiatement ce changement, mais votre code TypeScript ne s’en aperçoit que lorsque quelque chose échoue en temps de exécution. Il existe une version plus subtile du même risque. Disons que vous récupérez la première ligne.
const user = result.rows[0];
Puis vous lisez une propriété à partir de celle-ci, avec une faute d’orthographe.
console.log(user.emial);
La faute de frappe emial ne provoque aucune erreur de la part de JavaScript. On ne la découvre que lorsque cette ligne s’exécute et provoque un problème pour l’utilisateur. C’est précisément ce type de problème qui explique l’existence même des ORM.
Qu’est-ce qu’un ORM vraiment
ORM signifie Object Relational Mapping, ce qui semble plus impressionnant qu’en réalité. Il s’agit simplement d’un pont entre votre langage de programmation et votre base de données. Au lieu d’écrire manuellement une requête comme celle-ci,
SELECT *
FROM users
WHERE id=1;
Vous écrivez quelque chose qui ressemble davantage à une appel de méthode sur un objet.
user.findUnique({
id: 1
})
L’ORM prend cela et génère en arrière-plan le véritable SQL, de sorte que votre code passe par l’ORM pour arriver à une requête générée, puis à la base de données.
Your TypeScript code
|
vORM |
vSQL query |
vDatabase
Les équipes recourent aux ORM car les applications modernes exigent plus qu’un simple moyen d’envoyer des requêtes. Elles recherchent une sécurité de type, des migrations réelles, une gestion de schéma qui ne dépend pas de la mémorisation de chaque table, ainsi que beaucoup moins de code générique répétitif. Dans le monde actuel de TypeScript, les noms qui reviennent le plus souvent sont Prisma, Drizzle, TypeORM et Sequelize. L’attention se porte ici sur le SQL brut, Prisma et Drizzle, car ces trois outils couvrent ce que la plupart des backends modernes en TypeScript prennent réellement en compte.
Connaître Prisma
Prisma fait partie des ORM les plus discutés dans l’écosystème TypeScript et est souvent le premier nom mentionné dans toute conversation concernant les backends modernes Node.js. Au cœur de son fonctionnement, il permet à une application TypeScript de communiquer avec une base de données via du TypeScript ordinaire, sans SQL partout, et il prend en charge PostgreSQL, MySQL, SQLite, SQL Server et MongoDB. Vous écrivez en TypeScript, et Prisma le transforme en requêtes.
TypeScript code
|
vPrisma Client |
vSQL queries |
vDatabase
Une configuration typique d’Express, Prisma et PostgreSQL est organisée de manière claire : les requêtes entrent par l’API, passent par une couche de services, puis atteignent la base de données via Prisma Client.
Client
|
vExpress API |
vService Layer |
vPrisma Client |
vPostgreSQL Database
Prisma Client est l’élément qui effectue le travail réel : il constitue le véritable pont entre votre code backend et la base de données qui le soutient. Tout commence par un seul fichier, schema.prisma, qui décrit l’ensemble de la structure de la base de données en un seul endroit. Un modèle d’utilisateur, par exemple, définit quatre colonnes de type spécifié.
model User {
id Int @id @default(autoincrement())
name String
email String @unique
password String
}
Ce bloc indique à Prisma de créer une table User avec ces colonnes, et Prisma comprend parfaitement ce que cela implique. Alors que le SQL brut nécessiterait une instruction explicite pour créer la même table,
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT,
email TEXT UNIQUE,
password TEXT
);
Prisma a besoin uniquement du bloc de schéma ci-dessus et s’occupe de le traduire en véritables modifications de base de données au moyen d’une migration. Une migration est essentiellement un historique enregistré des changements apportés à la base de données au fil du temps. Supposons que votre table d’utilisateurs parte d’un schéma minimal.
User
id
name
email
Des mois plus tard, vous souhaitez ajouter un numéro de téléphone. Plutôt que de modifier la table manuellement, vous exécutez une seule commande.
npx prisma migrate dev --name add_phone_number
Prisma génère un fichier de migration pour enregistrer ce changement, de sorte que le dossier passe d’une migration de configuration initiale à une autre qui ajoute le numéro de téléphone ; l’historique complet reste ainsi versionné au lieu de rester dans la mémoire de quelqu’un. Une fois le schéma défini, Prisma génère un client que l’on utilise dans le code, par exemple pour récupérer un utilisateur par son identifiant.
const user = await prisma.user.findUnique({
where:{
id:1
}
});
Dans l’ombre, cela devient silencieusement du SQL ordinaire.
SELECT *
FROM users
WHERE id=1;
Vous n’avez jamais eu à taper vous-même le SQL. Les opérations quotidiennes s’adaptent de manière intuitive : une insertion devient une requête create, la récupération de toutes les données devient une requête find-many, la mise à jour d’un enregistrement devient une requête update conditionnée par une clause where, et la suppression devient une requête delete. C’est surtout en matière de sécurité des types que Prisma gagne sa réputation. Si votre schéma définit un User avec un id, un nom et un email, alors les requêtes vous offrent un véritable complétion automatique pour chaque champ.
const user = await prisma.user.findMany();
user[0].email;
En écrivant par erreur user[0].emali, Prisma, en collaboration avec TypeScript, détecte l’erreur avant même que l’application ne s’exécute, ce qui permet d’économiser une quantité surprenante de temps lors du débogage avec le temps. Bien sûr, les applications réelles n’ont que rarement une seule table. Supposons qu’un utilisateur possède de nombreux posts : il y a alors une table pour les utilisateurs et une autre pour les posts, reliées entre elles par un identifiant d’utilisateur.
User
id
namePostid
title
userId
Prisma exprime cette relation directement dans le schéma, tant dans le modèle d’utilisateur que dans les autres éléments.
model User {
id Int @id @default(autoincrement())
et le modèle de publication, qui fait référence à son utilisateur via une relation.
name String posts Post[]
}model Post { id Int @id @default(autoincrement()) title String userId Int user User @relation(
fields:[userId],
references:[id]
)}
Récupérer un utilisateur ainsi que ses publications devient alors une seule requête lisible qui inclut les enregistrements associés.
const user = await prisma.user.findUnique({
where:{
id:1
},
include:{
posts:true
}
});
Cela renvoie un objet utilisateur contenant un tableau imbriqué de publications, exactement la structure souhaitée dans le code de l’application. Les forces de Prisma résident dans le confort de l’expérience de développement, la robustesse de sa sécurité de type dans les projets TypeScript, l’ordre avec lequel se déroulent les migrations, la qualité de sa documentation, ainsi que la vitesse à laquelle toute une équipe peut lire le schéma et comprendre la structure de la base de données.
Cela n’est pas dépourvu de compromis. La génération de rapports véritablement complexes peut sembler peu pratique par rapport à des requêtes SQL manuscrites. Comme Prisma cache efficacement le SQL, les développeurs qui n’apprennent que Prisma ont parfois du mal plus tard lorsqu’ils doivent optimiser au niveau de la base de données. De plus, il y a techniquement un étape supplémentaire dans le parcours de la requête, allant de l’application à Prisma, puis au SQL, enfin à la base de données, au lieu du chemin plus court de l’application directement au SQL puis à la base de données. Pour la plupart des applications, cette couche supplémentaire ne pose pas de problème, mais il est utile de savoir qu’elle existe. Prisma convient le mieux lorsque vous développez des API en TypeScript, que vous souhaitez un développement rapide, que vous avez principalement besoin des opérations standards de création, lecture, mise à jour et suppression, et que vous accordez une grande importance à l’expérience des développeurs, c’est pourquoi de nombreuses startups et produits SaaS s’en servent.
Où s’inscrit Drizzle
Drizzle est un autre ORM qui a gagné en popularité dans TypeScript, et pour le comprendre, il faut d’abord reconnaître que Prisma et Drizzle s’appuient sur des philosophies véritablement différentes. Prisma cherche à tenir les développeurs à l’écart de la complexité des bases de données autant que possible. Drizzle adopte une approche inverse : il maintient les développeurs proches du SQL et ajoute simplement la sécurité offerte par TypeScript par-dessus. Tous deux visent le même objectif, à savoir une meilleure expérience de travail avec la base de données, mais par des voies très différentes. Drizzle est un ORM léger pour TypeScript, compatible avec PostgreSQL, MySQL et SQLite, axé sur la sécurité des types, les performances, le maintien d’une proximité avec le SQL et une architecture simplifiée. Vous écrivez toujours du TypeScript qui est transmis via Drizzle pour former une requête et être envoyée à la base de données.
TypeScript code
|
vDrizzle ORM |
vSQL query |
vDatabase
En plaçant les deux côte à côte, l’écart philosophique devient évident. La récupération de tous les utilisateurs via Prisma se fait selon la forme indiquée ci-dessous, et le SQL généré en arrière-plan ne vient que rarement à l’esprit.
const user = await prisma.user.findMany();
Drizzle demande quelque chose qui ressemble beaucoup plus au SQL réel.
const users = await db
.select()
.from(usersTable);
On peut pratiquement lire le comportement au niveau de la base de données directement dans le code. Les schémas diffèrent également. Prisma les stocke dans un fichier dédié schema.prisma, tandis que Drizzle déclare le schéma en TypeScript pur, après avoir d’abord importé les outils de création de colonnes nécessaires.
import {
pgTable,
serial,
varchar
} from "drizzle-orm/pg-core";
et déclarer le tableau avec des colonnes de type prédéfini.
export const users = pgTable("users", { id: serial("id").primaryKey(), name: varchar("name"), email: varchar("email")});
La structure de votre base de données se trouve donc directement à l’intérieur du codebase TypeScript, sans nécessiter de schéma supplémentaire à gérer. Les opérations quotidiennes ressemblent à du SQL vêtu de l’habit de TypeScript : une insertion correspond à une appel avec des valeurs, la lecture de tous les données s’effectue via un select depuis la table, et le filtrage ajoute une clause where construite à l’aide d’un outil d’égalité. Les gens choisissent Drizzle pour plusieurs raisons. Il est véritablement léger, avec peu d’abstraction. Comme il reste proche du SQL, vos compétences en SQL se perfectionnent plutôt que de s’atrophier derrière une abstraction. Ses requêtes générées sont généralement prévisibles, car moins de mécanismes se situent entre votre intention et le résultat. De plus, il a été conçu en tenant compte des environnements modernes, y compris les environnements edge et serverless.
D’un autre côté, si vous n’avez jamais vraiment appris SQL, Drizzle peut sembler plus confus au début que Prisma, qui constitue généralement une introduction plus douce pour les débutants. Utiliser correctement Drizzle exige réellement de comprendre les jointures, les relations, les index ainsi que le comportement des requêtes, sans aucune dissimulation. Et bien que son écosystème, sa documentation et sa communauté soient solides, ils restent plus petits que l’environnement plus mature de Prisma. La manière la plus claire de décrire cette différence est la suivante : avec Prisma, on traite la base de données comme un ensemble d’objets et l’accent est mis sur l’expérience utilisateur, tandis qu’avec Drizzle, on traite la base de données davantage comme le SQL lui-même, et l’accent se déplace vers les performances et le contrôle.
Les trois approches côte à côte
Avec ces trois solutions en vue, leurs architectures forment un spectre montrant le nombre de couches situées entre l’application et la base de données.
Raw SQL: Application → SQL Query → Database
Prisma: Application → Prisma Client → SQL → Database
Drizzle: Application → Drizzle → SQL → Database
Considérons une opération simple : trouver un utilisateur par e-mail dans une table de base d’utilisateurs. En SQL brut, on envoie directement une requête paramétrée.
const result = await pool.query(
`
SELECT *
FROM users
WHERE email=$1
`,
["rahul@test.com"]
);
Dans Prisma, on effectue une recherche unique.
const user =
await prisma.user.findUnique({
transférer l’adresse e-mail dans une clause where.
where:{
<email:"rahul@test.com>"
}});
Dans Drizzle, vous créez une sélection restreinte par une égalité sur la colonne e-mail.
const user =
await db
.select()
.from(users)
.where(
eq(
users.email,
"rahul@test.com"
)
);
Tous les trois restituent finalement les mêmes données. Ce qui diffère, c’est le degré de contrôle souhaité, le niveau d’abstraction auquel on se sent à l’aise, ainsi que les connaissances en SQL déjà possédées. Une erreur fréquente chez les débutants est de se concentrer sur le choix du outil le plus rapide, alors que dans les projets réels, la vitesse est rarement le critère décisif. Les questions plus pertinentes sont celles concernant les compétences déjà maîtrisées par l’équipe, le degré réel de complexité du projet, la profondeur des connaissances en base de données de chacun, et le degré de complexité probable des requêtes. Une application SaaS simple se passe généralement très bien avec Prisma seul, tandis que pour les applications à forte charge en base de données, c’est Drizzle, ou l’usage de SQL brut en certains endroits, qui devient indispensable.
En résumant les compromis en termes simples : la courbe d’apprentissage est la plus difficile avec SQL brut, la plus facile avec Prisma, et modérée avec Drizzle. Le contrôle sur le SQL est le plus élevé avec SQL brut, élevé avec Drizzle, et le plus bas avec Prisma. La sécurité des types est faible avec SQL brut, mais excellente tant avec Prisma qu’avec Drizzle. Les performances brutes sont excellentes pour SQL brut et Drizzle, et bonnes pour Prisma. L’expérience des développeurs est la meilleure avec Prisma, bonne avec Drizzle, et moyenne avec SQL brut. Les requêtes complexes favorisent SQL brut et Drizzle, avec Prisma à un niveau intermédiaire. En ce qui concerne la facilité d’utilisation pour les débutants, Prisma est en tête, Drizzle est intermédiaire, et SQL brut est en retard.
Alors, lequel choisir ?
Un ORM doit-il toujours être le choix par défaut ? Honnêtement, non. Comme tout autre outil, un ORM convient pour certaines tâches mais pas pour d’autres, et rien ne s’adapte à tous les projets. Le SQL brut trouve sa place lorsque l’on a besoin d’un contrôle maximal, lorsque l’application repose fortement sur une base de données, lorsque les requêtes deviennent complexes, ou lorsque les performances ne peuvent absolument pas être compromises. Les plateformes d’analyse, les systèmes de rapport et les applications financières sont des cas d’usage appropriés, tout comme tout ce qui nécessite le traitement de volumes importants de données. Un rapport indiquant par exemple combien chaque client a acheté au cours de cinq ans, ainsi que la valeur moyenne de sa commande, est naturellement plus facile à établir directement en SQL en sélectionnant les agrégats.
SELECT
customers.name,
COUNT(orders.id),
AVG(orders.amount)
et les combiner et les regrouper pour les créer.
FROM customersJOIN ordersON customers.id = orders.customer_idGROUP BY customers.name;
Pour ce type de tâche, rien ne remplace vraiment ce que SQL peut exprimer. Le problème, c’est que compter sur du SQL manuel pour tout dans une grande base de code devient rapidement peu pratique, ce qui entraîne des centaines de fichiers de requêtes dispersés un peu partout, ainsi qu’une sécurité de type dont il faut s’occuper soi-même. Une vue classée par priorité de la performance de l’API Node.js montre à quel point c’est la base de données, et non le framework, qui détermine réellement les gains et les pertes.
Prisma s’avère généralement la meilleure solution lorsque vous développez un backend en TypeScript, que vous effectuez principalement des opérations standards de création, lecture, mise à jour et suppression, que vous valorisez la vitesse de développement et que vous coordonnez plusieurs développeurs au sein d’une même base de code. Cela correspond aux produits SaaS, aux tableaux de bord administratifs, aux API de boutiques en ligne et aux systèmes de gestion de contenu, où les tâches quotidiennes consistent à créer un utilisateur, à mettre à jour un profil, à passer une commande ou à récupérer des données de tableau de bord. Prisma améliore réellement la productivité en transformant une requête brute en une appel propre et lisible que n’importe quel collègue peut comprendre d’un coup d’œil. Drizzle trouve sa place lorsque vous travaillez en TypeScript, que vous connaissez déjà bien SQL, que vous vous souciez de la performance et du contrôle, et que vous préférez une solution légère plutôt qu’une lourde. Elle convient aux développeurs qui souhaitent la sécurité offerte par un ORM sans se sentir trop éloignés de la base de données.
En pratique, de nombreux projets réels ne s’en tiennent pas à une seule approche. Une startup peut raisonnablement commencer par un chemin direct allant d’Express, en passant par Prisma, jusqu’à PostgreSQL.
Express → Prisma → PostgreSQL
C’est une première étape vraiment sensée. Plus tard, lorsque le produit se développe et que des besoins d’analyse ou de génération de rapports plus complexes apparaissent, les équipes ajoutent souvent du SQL brut dans certains endroits plutôt que de supprimer Prisma, ce qui conduit à une application qui accède à PostgreSQL à la fois via Prisma et des requêtes manuscrites.
Application
├── Prisma
└── Raw SQL Queries
↓
PostgreSQL
Il n’existe pas de règle imposant d’utiliser une seule approche partout, et la plupart des bases de code réelles finissent par les mélanger. Les startups ont souvent recours à TypeScript, Prisma et PostgreSQL uniquement pour gagner en vitesse. Les projets TypeScript plus récents privilégient de plus en plus Drizzle et son style léger adapté à SQL. De leur côté, les systèmes plus importants combinent fréquemment un ORM avec du SQL brut et des outils dédiés à l’optimisation des bases de données, simplement parce que différentes parties d’un grand système rencontrent des problèmes distincts.
Erreurs à éviter
Quelques erreurs récurrentes se produisent. La première consiste à traiter l’ORM comme s’il s’agissait de la base de données. Prisma n’est pas une base de données, tout comme Drizzle ; ce sont des outils permettant d’y accéder, que ce soit PostgreSQL, MySQL ou MongoDB en dessous. La deuxième erreur est de contourner complètement SQL pour passer directement à Prisma. Cela semble productif au début, mais cela finit généralement par poser des problèmes, lorsque les requêtes lentes deviennent inexplicables, que les jointures semblent inutilement complexes, et que l’optimisation devient véritablement difficile en l’absence de fondements sous l’abstraction. Un ORM n’a jamais été conçu pour remplacer SQL ; il fonctionne au-dessus de celui-ci. La troisième erreur est de privilégier avant tout des chiffres de performance bruts. La productivité des développeurs est tout aussi importante dans le monde réel, et gagner cinq millisecondes sur une requête au détriment d’un développement trois mois plus lent n’est rarement le meilleur compromis.
Un parcours d’apprentissage qui en vaut la peine
En partant de zéro aujourd’hui, une approche logique consiste à commencer par les fondamentaux de SQL, notamment les tables, les clés primaires, les clés étrangères, les jointures, les index et les transactions, en utilisant un système comme PostgreSQL. Ensuite, travaillez directement avec un pilote tel que le paquet pg de Node pour comprendre comment une application communique avec une base de données sans aucun intermédiaire. Après cela, passez à Prisma et familiarisez-vous avec les schémas, les migrations, les relations ainsi que sa sécurité de type. Enfin, essayez Drizzle pour découvrir ce qu’offre un constructeur de requêtes axé sur SQL, ainsi que les compromis en termes de performance qu’il implique.
Où cela vous mène
Le but d’un ORM n’a jamais été de remplacer SQL. Il existe pour améliorer l’expérience du développeur, et rien de plus important que cela. Un développeur backend véritablement compétent n’est pas défini par sa maîtrise de Prisma ou de Drizzle. C’est quelqu’un qui comprend comment fonctionne réellement une base de données, qui sait écrire du SQL lorsque c’est nécessaire, qui connaît ce que l’ORM simplifie à sa place, et, tout aussi important, qui sait quand il est judicieux d’utiliser un ORM et quand du SQL écrit manuellement est la meilleure solution. Une fois cette clarté acquise, choisir parmi ces outils cesse d’être une question de suppositions. On commence alors à décider en fonction des besoins réels du projet, et non en fonction de ce qui est à la mode ce mois-ci.
Lectures complémentaires
- Idées reçues courantes sur Node.js et les bases de données qui causent des bugs en production : Découvrez pourquoi async/await, le pooling de connexions et les ORM ne préviennent pas automatiquement les conditions de concurrence, l’épuisement des connexions ou les injections SQL dans les applications Node.js.
- Équilibrer la génération CRUD Prisma avec un contrôle routier délibéré : Apprenez comment la génération de routes CRUD Prisma pilotée par le schéma peut éliminer le code générique répétitif tout en conservant les décisions relatives à la confiance, au cadrage et à l’exposition dans le code de l’application.