← L'édition
DevNouveau2 min de lecture

Pourquoi l'architecture backend gagne à dépasser le modèle traditionnel des ORM

L'usage systématique des ORM dans les applications web pose des questions croissantes de performance et d'abstraction surdimensionnée. En revenant à du SQL brut encapsulé dans des magasins de données dédiés, les équipes d'ingénierie réduisent l'empreinte mémoire et tirent pleinement parti des capacités natives des bases relationnelles.

Fil « Réflexion sur les alternatives aux ORM pour la gestion de bases de données »

Les limites fondamentales du mapping objet-relationnel

L'utilisation d'un ORM (Object-Relational Mapping, technique de correspondance entre objets logiciels et tables relationnelles) est devenue le choix par défaut dans de nombreux frameworks. Cependant, cette couche d'abstraction impose un coût de performance élevé en matière d'allocation mémoire et de temps processeur pour transformer chaque ligne de la base de données en objet complet. De plus, elle masque souvent des fonctionnalités SQL avancées comme les fonctions de fenêtrage (window functions, calculs d'agrégation sur un sous-ensemble de lignes) ou les requêtes CTE (Common Table Expressions, expressions de table communes pour structurer des requêtes complexes).

Exploiter la puissance SQL native avec la clause RETURNING

Les ORM incitent fréquemment à multiplier les aller-retours avec la base de données. Par exemple, pour supprimer des enregistrements tout en récupérant leur contenu, une approche ORM classique exécute d'abord une requête SELECT puis une série de requêtes DELETE. Des bases relationnelles comme PostgreSQL ou SQLite permettent d'exécuter cette opération en un seul aller-retour grâce à la clause RETURNING.

DELETE FROM beads 
WHERE material = 'wood' 
RETURNING *;

Repenser le composant Modèle dans l'architecture MVC

Dans l'architecture MVC (Modèle-Vue-Contrôleur, patron d'architecture séparant les données, l'affichage et la logique métier), le modèle est traditionnellement assimilé à une entité ORM dotée d'une API (Application Programming Interface, interface de programmation) très vaste. Une approche alternative consiste à encapsuler les requêtes dans des classes dédiées (Store ou Repository) qui renvoient directement des structures de données brutes (des dictionnaires ou cartes clé-valeur) plutôt que des instances d'objets lourdes.

class PostsStore
  def initialize(db)
    @db = db
  end

  def create(title:, body:)
    @db.query_single_row(<<~SQL, title, body)
      INSERT INTO posts (title, body) 
      VALUES (?, ?) 
      RETURNING id;
    SQL
  end
end

Réduire la complexité inutile du code

Une application web n'exécute en pratique qu'un nombre fini et relativement restreint de requêtes par table. L'utilisation d'un DSL (Domain-Specific Language, langage dédié servant ici à construire dynamiquement des requêtes) complexe s'avère souvent surdimensionnée. Définir des requêtes SQL explicites dans une couche d'accès aux données simplifie la maintenance, élimine la magie implicite des ORM et garantit une maîtrise totale des performances de la base de données.