Notificações em tempo real (SSE)

2 min de leitura

Notificações em tempo real (SSE)

Assine canais PostgreSQL NOTIFY via Server-Sent Events:

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

Cada mensagem é JSON com o canal e o payload:

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

Se o payload for texto, ele é encapsulado como string em data.

Os canais não são restritos por função (role)

Ao contrário dos endpoints JSON-RPC e MCP, o SSE não aplica SET LOCAL ROLE nem verifica de outra forma as permissões da role autenticada antes da assinatura. O PgArachne autentica quem chama (um JWT válido, um token de API ou credenciais diretas para o banco de dados de destino), mas qualquer chamador autenticado — independentemente da role a que suas credenciais correspondem — pode assinar qualquer canal NOTIFY e receberá tudo o que for publicado nele. Isso decorre de como o endpoint é construído: todos os clientes SSE de um banco de dados compartilham uma única conexão LISTEN aberta como a conta de serviço DB_USER, e o próprio PostgreSQL não possui nenhum GRANT por canal ao qual delegar — canais LISTEN/NOTIFY não são objetos de banco de dados.

Não envie via NOTIFY payloads com dados que nem toda role autenticada deveria ver. Se você precisar de controle de acesso em nível de canal, implemente-o na sua própria lógica de aplicação (por exemplo, convenções de nomenclatura de canais por role, ou filtrando o que você coloca no payload) — o PgArachne não fará isso por você nesse endpoint.

Enviar notificações a partir do PostgreSQL

A partir do psql ou de qualquer sessão de banco de dados:

-- Payload de texto simples
NOTIFY orders, 'novo pedido';

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

A partir de um trigger ou stored procedure:

PERFORM pg_notify('orders', json_build_object('id', NEW.id, 'status', NEW.status)::text);
Nota: NOTIFY só é entregue às outras sessões após o commit da transação remetente. Se você o executar dentro de uma transação aberta no psql, os assinantes só o receberão após o COMMIT.