Questo articolo estende due confronti già pubblicati su questo blog: la nostra recensione della compatibilità PostgREST e le sue alternative e il nostro confronto dedicato ai layer GraphQL su Postgres. Qui l'angolo cambia: una griglia decisionale tra tre modi per costruire un livello API, con Hasura trattato per i suoi permessi e punti di estensione aziendale piuttosto che per la sua sintassi GraphQL, e un'API scritta a mano come opzione a sé stante, non una semplice riga "else" in fondo alla tabella.
L'essenziale
- PostgREST genera automaticamente un'API REST dallo schema Postgres: non è possibile alcuna logica aziendale arbitraria, la RLS rimane l'unico limite di sicurezza.
- Hasura aggiunge il proprio sistema di autorizzazioni per ruolo e tabella, azioni per connettere un webhook aziendale, trigger di eventi ed endpoint RESTificati sul suo motore GraphQL.
- Un'API personalizzata (Node.js, Express, Fastify...) offre il controllo totale sulla logica aziendale, sulla convalida e sull'autenticazione, al costo di scrivere, testare e mantenere tutto da soli.
- Su Aurabase, il livello PostgREST è un'istanza reale; la logica aziendale oltre CRUD passa attraverso le funzioni SQL esposte in RPC o tramite Edge Functions, non tramite un server Node separato da ospitare.
- I tre approcci non si escludono necessariamente a vicenda: la combinazione di PostgREST per CRUD e un'API personalizzata per operazioni sensibili è uno schema comune nella produzione.
La vera scelta: chi scrive la logica aziendale e dove
La domanda “PostgREST o Hasura o API personalizzata” nasconde una domanda più utile: chi scrive la tua logica aziendale, con quale strumento e chi utilizza questo codice in produzione? Le tre architetture rispondono in modo diverso e questa differenza struttura tutto il resto: sicurezza, velocità di implementazione, debito tecnico a lungo termine.
| Origine dell'API | Generato dallo schema SQL | Generato dallo schema, tramite il motore GraphQL Hasura | Scritto percorso per percorso, a mano |
|---|---|---|---|
| Logica aziendale personalizzata | Solo funzioni SQL (RPC). | Azioni (webhook) + Trigger di eventi | Qualsiasi codice, senza vincoli di strumento |
| Modello di sicurezza | RLS Postgres, ruolo guidato da JWT | Autorizzazioni specifiche per ruolo/tabella, non delega alla RLS | Cosa codifichi (middleware, ORM, RLS opzionale) |
| Per ospitare in aggiunta | Niente: un binario leggero | Il motore Hasura, con la propria base di metadati | Il server applicativo completo |
| Curva di apprendimento | Basso se il team sa già come scrivere SQL | Medio: un nuovo sistema di autorizzazioni e configurazione | Niente sullo strumento, ma tutto il resto da progettare |
| POSTGREST | HASURA | API PERSONALIZZATA |
Nessuna delle tre colonne è strettamente migliore: ciascuna sposta il lavoro altrove. PostgREST lo sposta in SQL, Hasura nella configurazione e nei webhook, un'API personalizzata nel codice dell'applicazione classica.
PostgREST: l'API come riflesso diretto dello schema
PostgREST trasforma il tuo schema Postgres in un'API REST: filtri, incorporamento di relazioni, RPC, RLS guidati da JWT, senza backend da scrivere. Descriviamo dettagliatamente questo ambito nel nostro articolo sulla sua reale compatibilità e le sue alternative; ciò che conta per questo confronto è dove si ferma PostgREST.
PostgREST non ha alcuna nozione di logica aziendale arbitraria. Ogni regola deve essere espressa in SQL: una funzione RPC, un trigger, un vincolo, una policy RLS. Si tratta di un vincolo accettato, non di una svista: il diagramma rimane l'unica fonte di verità, che elimina qualsiasi deriva tra il livello dell'applicazione e la base che serve.
Concretamente, è impossibile chiamare un servizio di pagamento di terze parti, inviare un'e-mail di conferma o calcolare un punteggio in JavaScript da una richiesta PostgREST diretta. Questa logica deve vivere in SQL (funzione pl/pgsql) o essere attivata all'esterno: un trigger che pubblica un evento NOTIFY, ascoltato da un servizio esterno che non è più PostgREST.
Hasura: permessi dichiarati, logica di business innestata dal webhook
Il nostro articolo sui livelli GraphQL su Postgres descrive dettagliatamente dove viene eseguito il motore Hasura e come le sue autorizzazioni differiscono da Postgres RLS. In questo caso, la questione è quella della logica aziendale: come inserire il codice personalizzato in un database gestito da Hasura, e dove.
Un'azione Hasura espone una mutazione o query GraphQL personalizzata, supportata da un webhook HTTP scritto nella lingua di tua scelta. Hasura convalida gli input in base allo schema dichiarato, chiama il tuo webhook, quindi restituisce la sua risposta al client. È la porta d’accesso a qualsiasi logica che vada oltre la CRUD: chiamata a un fornitore di servizi di pagamento, calcolo complesso, orchestrazione in più fasi.
Gli Event Trigger seguono la direzione opposta: un inserimento, un aggiornamento o una cancellazione su una tabella innesca un webhook, in modo asincrono e con riavvio automatico in caso di fallimento. Questo è il meccanismo utilizzato dalla maggior parte delle integrazioni Hasura per sincronizzare un servizio di terze parti (fatturazione, e-mail transazionale, motore di ricerca) senza associare questo codice alla richiesta iniziale del cliente.
Hasura può anche esporre una query GraphQL già scritta come un tipico percorso REST, con un percorso denominato e parametri — i suoi endpoint RESTified, nella terminologia della propria documentazione. Utile se il tuo team frontend preferisce utilizzare REST, senza rinunciare al motore delle autorizzazioni GraphQL sottostante.
Le autorizzazioni Hasura sono un sistema specifico di Hasura, per ruolo e per tabella, non una delega a Postgres RLS. Due posti in cui controllare le regole di accesso anziché uno solo: un costo reale da valutare rispetto alla flessibilità ottenuta dalle azioni e dai trigger di eventi.
Promemoria contestuale, sviluppato nel nostro articolo dedicato: Hasura ha rifocalizzato la sua comunicazione su PromptQL, un layer progettato per agenti AI, da giugno 2025, senza rimuovere il suo motore GraphQL, ancora presentato come "testato in battaglia" sul suo sito ufficiale.
API personalizzate (Node.js, Express, Fastify): codifica tutto, controlla tutto
Un'API scritta a mano non ha, per definizione, limiti: qualsiasi logica aziendale, in qualsiasi lingua, con qualsiasi dipendenza. È anche l'unica delle tre opzioni in cui non viene generato nulla per te: ogni percorso, ogni convalida, ogni connessione al database è un codice di tua proprietà e che devi mantenere.
Ciò che offre questo modello, in cambio del lavoro manuale: controllo completo sugli errori e sui codici HTTP restituiti, testabilità classica (gestori, configurazione non dichiarativa) e nessun nuovo DSL da apprendere per un team che già padroneggia il suo linguaggio.
Quanto costa, in cambio: CRUD, impaginazione e filtri da scrivere e mantenere a mano per ogni risorsa; autenticazione e autorizzazione per implementare e verificare autonomamente, senza RLS ereditata automaticamente; il rischio di N+1 query se ciascuna relazione annidata attiva la propria query Postgres senza disciplina; e documentazione API da mantenere manualmente o tramite un generatore di terze parti da integrare.
Per quanto riguarda le prestazioni grezze, la domanda "Node.js è più lento di Rust" è un argomento a sé stante: il nostro articolo su Latenza di Rust e Node.js lo tratta in dettaglio, con la metodologia dichiarata a monte nella nostra pagina della metodologia di benchmark . Un'API personalizzata ha lo stesso profilo prestazionale di qualsiasi servizio HTTP che già utilizzi, né migliore né peggiore per costruzione. Per sapere con precisione dove PostgREST satura e a che punto diventa necessario un livello personalizzato, vedere il nostro articolo su i reali limiti di PostgREST in produzione.
Tabella comparativa: le tre opzioni affiancate
Al di là dell'architettura, al momento della scelta emergono molto spesso quattro criteri: velocità di implementazione, reale flessibilità aziendale, debito tecnico a lungo termine e caso d'uso tipico in cui ciascuna opzione è più comoda.
| Configurazione iniziale | Minuti: lo schema esiste già | Ore: collega la base, configura le autorizzazioni | Giorni o settimane: scrivi ogni percorso |
|---|---|---|---|
| Flessibilità aziendale | Limitato a SQL (RPC, trigger) | Buono tramite azioni/trigger di eventi, ma passa attraverso un webhook esterno | Totale, diretto |
| Debito tecnico a termine | Debole: il diagramma rimane l’unica fonte di verità | Medio: metadati Hasura da mantenere in aggiunta allo schema | Alto se il team cresce senza disciplina (test, documentazione, revisione) |
| Caso d'uso tipico | CRUD diretto su uno schema stabile, team a proprio agio in SQL | Federare diverse origini dati o logica orientata all'agente AI | Logica aziendale complessa, numerose integrazioni di terze parti |
| POSTGREST | HASURA | API PERSONALIZZATA |
Dove va a finire la logica aziendale in un progetto Aurabase
Su un progetto del motore Aurabase Postgres, il livello CRUD è già coperto da un'istanza PostgREST effettiva, non da una reimplementazione approssimativa. La domanda che resta aperta per questo confronto: dove scrivere ciò che va oltre il CRUD?
Esistono due percorsi e non si escludono a vicenda. Il primo: una funzione SQL esposta in RPC, per qualsiasi logica che sia ragionevole esprimere in SQL: calcolo di un totale, convalida incrociata tra più tabelle, aggiornamenti a cascata in un'unica transazione.
Il secondo modo: Edge Functions, per tutto ciò che va oltre il dominio SQL: chiamare un'API di pagamento, inviare un'e-mail, calcolare un incorporamento. Due percorsi conducono lì in Aurabase: l'editor Studio, che esegue il codice Deno (TypeScript) esattamente come su Supabase, e la aura functions deployCLI, che mira a un percorso separato per le funzioni scritte in Rust e compilate in WASM — dettagliate nella nostra architettura Rust unificata. Nessuno dei due percorsi richiede l'hosting di un server Node separato, a differenza della pura opzione "API personalizzata" in questo articolo, in cui quel server è interamente sotto la tua responsabilità.
Questa distribuzione non è un compromesso traballante tra i tre modelli qui confrontati: è letteralmente PostgREST per CRUD, un brick vicino ad Hasura Actions per la logica degli eventi tramite RPC e trigger, e Edge Functions che evitano il funzionamento di un application server completo - senza mai forzare una scelta binaria tra "tutto PostgREST" e "tutto personalizzato".
Come scegliere in base al contesto
Quattro situazioni si verificano più spesso. La scelta giusta dipende principalmente da ciò che richiede la tua logica aziendale, non dalla popolarità di uno strumento.
- Il tuo schema è stabile e la logica aziendale è in SQL. È sufficiente PostgREST self-hosted, o integrato nativamente (Aurabase, Supabase): niente più da ospitare, e lo schema rimane l'unica fonte di verità.
- Desideri riunire diverse origini dati oppure la tua roadmap è orientata agli agenti IA che utilizzano i tuoi dati. Hasura, con il suo layer PromptQL, si adatta meglio a questo terreno.
- Il tuo prodotto ha una ricca logica di business, numerose integrazioni di terze parti e un team già dotato di un linguaggio applicativo. Una API personalizzata rimane la scelta più diretta, a costo di scriverla e mantenerla nel tempo.
- Desideri CRUD autogenerati senza rinunciare allo spazio reale per la logica aziendale (RPC, Edge Functions), senza impilare un ulteriore servizio applicativo da sfruttare. Questo è l'angolo documentato in questo confronto applicato ad Aurabase, sezione precedente.