PostgREST vs Hasura vs API custom : que choisir pour un backend Postgres
Trois architectures répondent à la même question, chacune à sa manière : comment brancher une API sur une base Postgres sans tout écrire à la main. PostgREST génère une API REST depuis votre schéma SQL. Hasura génère une API GraphQL avec son propre système de permissions et des points d’extension pour votre logique métier. Une API custom, en Node.js ou ailleurs, vous donne le contrôle total, au prix de tout coder vous-même. Le bon choix dépend moins de la performance brute que de l’endroit où vous voulez que votre logique métier vive.
Cet article prolonge deux comparatifs déjà publiés sur ce blog : notre revue de la compatibilité PostgREST et de ses alternatives et notre comparatif dédié aux couches GraphQL sur Postgres. Ici, l’angle change : une grille de décision entre trois façons de construire une couche API, avec Hasura traité pour ses permissions et ses points d’extension métier plutôt que pour sa syntaxe GraphQL, et une API écrite à la main comme option à part entière, pas une simple ligne « sinon » en bas de tableau.
- PostgREST auto-génère une API REST depuis le schéma Postgres — pas de logique métier arbitraire possible, la RLS reste l’unique frontière de sécurité.
- Hasura ajoute son propre système de permissions par rôle et par table, des Actions pour brancher un webhook métier, des Event Triggers, et des endpoints RESTified au-dessus de son moteur GraphQL.
- Une API custom (Node.js, Express, Fastify...) donne le contrôle total sur la logique métier, la validation et l’auth — au prix de tout écrire, tester et maintenir soi-même.
- Sur Aurabase, la couche PostgREST est une instance réelle ; la logique métier au-delà du CRUD passe par des fonctions SQL exposées en RPC ou par les Edge Functions, pas par un serveur Node séparé à héberger.
- Les trois approches ne s’excluent pas forcément : combiner PostgREST pour le CRUD et une API custom pour les opérations sensibles est un pattern courant en production.
Le vrai choix : qui écrit la logique métier, et où
La question « PostgREST ou Hasura ou API custom » cache une question plus utile : qui écrit votre logique métier, avec quel outil, et qui exploite ce code en production ? Les trois architectures y répondent différemment, et cette différence structure tout le reste — sécurité, vitesse de mise en place, dette technique à terme.
Aucune des trois colonnes n’est strictement meilleure : chacune déplace le travail ailleurs. PostgREST le déplace vers le SQL, Hasura vers la configuration et des webhooks, une API custom vers du code applicatif classique.
PostgREST : l’API comme reflet direct du schéma
PostgREST transforme votre schéma Postgres en API REST — filtres, embedding de relations, RPC, RLS pilotée par JWT — sans backend à écrire. Nous détaillons ce périmètre en profondeur dans notre article sur sa compatibilité réelle et ses alternatives ; ce qui compte pour ce comparatif, c’est où PostgREST s’arrête.
PostgREST n’a pas de notion de logique métier arbitraire. Chaque règle doit s’exprimer en SQL : une fonction RPC, un trigger, une contrainte, une policy RLS. C’est une contrainte assumée, pas un oubli — le schéma reste la seule source de vérité, ce qui élimine toute dérive entre une couche applicative et la base qu’elle sert.
Concrètement, impossible d’appeler un service de paiement tiers, d’envoyer un email de confirmation, ou de calculer un score en JavaScript depuis une requête PostgREST directe. Cette logique doit soit vivre en SQL (fonction pl/pgsql), soit être déclenchée en dehors — un trigger qui publie un événement NOTIFY, écouté par un service externe qui, lui, n’est déjà plus du PostgREST.
Hasura : permissions déclarées, logique métier greffée par webhook
Notre article sur les couches GraphQL sur Postgres détaille où tourne le moteur Hasura et comment ses permissions diffèrent de la RLS Postgres. Ici, l’angle est celui de la logique métier : comment brancher du code personnalisé sur une base gérée par Hasura, et à quel endroit.
Une Action Hasura expose une mutation ou une query GraphQL personnalisée, adossée à un webhook HTTP que vous écrivez dans le langage de votre choix. Hasura valide les entrées selon le schéma déclaré, appelle votre webhook, puis retourne sa réponse au client. C’est la porte d’entrée pour toute logique qui dépasse le CRUD : appel à un prestataire de paiement, calcul complexe, orchestration multi-étapes.
Les Event Triggers suivent la direction inverse : un insert, un update ou un delete sur une table déclenche un webhook, de façon asynchrone et avec relance automatique en cas d’échec. C’est le mécanisme que la plupart des intégrations Hasura utilisent pour synchroniser un service tiers (facturation, email transactionnel, moteur de recherche) sans coupler ce code à la requête initiale du client.
Hasura peut aussi exposer une requête GraphQL déjà écrite comme une route REST classique, avec un chemin et des paramètres nommés — ses endpoints RESTified, dans la terminologie de sa propre documentation. Utile si votre équipe frontend préfère consommer du REST, sans renoncer au moteur de permissions GraphQL sous-jacent.
Rappel de contexte, développé dans notre article dédié : Hasura a recentré sa communication sur PromptQL, une couche pensée pour des agents IA, depuis juin 2025 — sans retirer son moteur GraphQL, toujours présenté comme « battle-tested » sur son site officiel.
API custom (Node.js, Express, Fastify) : tout coder, tout contrôler
Une API écrite à la main n’a, par définition, aucune limite : n’importe quelle logique métier, dans n’importe quel langage, avec n’importe quelle dépendance. C’est aussi la seule des trois options où rien n’est généré pour vous — chaque route, chaque validation, chaque connexion à la base est du code que vous possédez et que vous devez maintenir.
Ce que ce modèle offre, en échange du travail manuel : contrôle total sur les erreurs et les codes HTTP retournés, testabilité classique (des handlers, pas une configuration déclarative), et aucun nouveau DSL à apprendre pour une équipe qui maîtrise déjà son langage.
Ce qu’il coûte, en échange : le CRUD, la pagination et les filtres à écrire et maintenir à la main pour chaque ressource ; l’authentification et l’autorisation à implémenter et auditer vous-même, sans RLS héritée automatiquement ; le risque de requêtes N+1 si chaque relation imbriquée déclenche sa propre requête Postgres sans discipline ; et une documentation d’API à maintenir manuellement, ou via un générateur tiers à intégrer.
Sur la performance brute, la question « Node.js est-il plus lent que Rust » est un sujet à part entière — notre article sur la latence Rust vs Node.js le traite en détail, avec méthodologie déclarée en amont sur notre page de méthodologie de benchmark. Une API custom a le même profil de performance que n’importe quel service HTTP que vous exploitez déjà, ni mieux ni pire par construction. Pour savoir précisément où PostgREST sature et à partir de quel point une couche custom devient nécessaire, voir notre article sur les limites réelles de PostgREST en production.
Tableau comparatif : les trois options côte à côte
Au-delà de l’architecture, quatre critères reviennent le plus souvent au moment de choisir : la vitesse de mise en place, la flexibilité métier réelle, la dette technique à terme, et le cas d’usage type où chaque option est la plus à l’aise.
Où va la logique métier sur un projet Aurabase
Sur un projet Aurabase moteur Postgres, la couche CRUD est déjà couverte par une instance PostgREST réelle, pas une réimplémentation approchée. La question qui reste ouverte pour ce comparatif : où écrire ce qui dépasse le CRUD ?
Deux voies existent, et elles ne s’excluent pas. La première : une fonction SQL exposée en RPC, pour toute logique qui reste raisonnable à exprimer en SQL — calcul d’un total, validation croisée entre plusieurs tables, mise à jour en cascade dans une seule transaction.
La seconde voie : les Edge Functions, pour tout ce qui sort du domaine SQL — appeler une API de paiement, envoyer un email, calculer un embedding. Deux chemins y mènent chez Aurabase : l’éditeur du Studio, qui exécute du code Deno (TypeScript) exactement comme sur Supabase, et la CLI aura functions deploy, qui vise un chemin distinct pour des fonctions écrites en Rust et compilées en WASM — détaillé dans notre architecture Rust unifiée. Aucun des deux chemins n’exige d’héberger un serveur Node séparé, contrairement à l’option « API custom » pure de cet article, où ce serveur est entièrement à votre charge.
Cette répartition n’est pas un compromis bancal entre les trois modèles comparés ici : c’est littéralement PostgREST pour le CRUD, une brique proche des Actions Hasura pour la logique événementielle via RPC et triggers, et des Edge Functions qui évitent l’exploitation d’un serveur applicatif complet — sans jamais forcer un choix binaire entre « tout PostgREST » et « tout custom ».
Quatre situations reviennent le plus souvent. Le bon choix dépend surtout de ce que votre logique métier exige, pas de la popularité d’un outil.
- Votre schéma est stable et votre logique métier tient en SQL. PostgREST auto-hébergé, ou intégré nativement (Aurabase, Supabase), suffit : rien à héberger en plus, et le schéma reste la seule source de vérité.
- Vous voulez fédérer plusieurs sources de données, ou votre feuille de route s’oriente vers des agents IA consommant vos données. Hasura, avec sa couche PromptQL, correspond mieux à ce terrain.
- Votre produit a une logique métier riche, des intégrations tierces nombreuses, et une équipe déjà outillée sur un langage applicatif. Une API custom reste le choix le plus direct, au prix de l’écrire et de la maintenir dans la durée.
- Vous voulez le CRUD auto-généré sans renoncer à un espace réel pour la logique métier (RPC, Edge Functions), sans empiler un service applicatif de plus à exploiter. C’est l’angle que documente ce comparatif appliqué à Aurabase, section précédente.
Comment choisir selon votre contexte