Notifiche in tempo reale (SSE)

2 min di lettura

Notifiche in tempo reale (SSE)

Iscriviti ai canali PostgreSQL NOTIFY tramite Server-Sent Events:

curl -N "http://localhost:8080/db/my_database/sse?channels=orders,users" \
  -H "Authorization: Bearer $TOKEN"

Ogni messaggio è JSON con il canale e il payload:

{"channel":"orders","data":{"id":123,"status":"created"}}

Se il payload è testo, viene incapsulato come stringa in data.

I canali non sono limitati per ruolo

A differenza degli endpoint JSON-RPC e MCP, SSE non applica SET LOCAL ROLE né verifica in altro modo i permessi del ruolo autenticato prima della sottoscrizione. PgArachne autentica il chiamante (un JWT valido, un token API o credenziali dirette per il database di destinazione), ma qualsiasi chiamante autenticato — indipendentemente dal ruolo a cui corrispondono le sue credenziali — può sottoscrivere qualsiasi canale NOTIFY e riceverà tutto ciò che vi viene pubblicato. Questo deriva da come è costruito l’endpoint: tutti i client SSE di un database condividono un’unica connessione LISTEN aperta come account di servizio DB_USER, e PostgreSQL stesso non dispone di alcun GRANT per canale a cui delegare — i canali LISTEN/NOTIFY non sono oggetti del database.

Non inviare tramite NOTIFY payload con dati che non ogni ruolo autenticato dovrebbe vedere. Se hai bisogno di un controllo degli accessi a livello di canale, implementalo nella tua logica applicativa (ad es. convenzioni di denominazione dei canali per ruolo, o filtrando ciò che inserisci nel payload) — PgArachne non lo farà per te su questo endpoint.

Inviare notifiche da PostgreSQL

Da psql o qualsiasi sessione di database:

-- Payload testo semplice
NOTIFY orders, 'nuovo ordine';

-- Payload JSON
NOTIFY orders, '{"id":123,"status":"created"}';

Da un trigger o una stored procedure:

PERFORM pg_notify('orders', json_build_object('id', NEW.id, 'status', NEW.status)::text);
Nota: NOTIFY viene consegnato alle altre sessioni solo dopo il commit della transazione mittente. Se lo esegui all’interno di una transazione aperta in psql, i sottoscrittori lo riceveranno solo dopo il COMMIT.