Сповіщення в реальному часі (SSE)

2 хв читання

Сповіщення в реальному часі (SSE)

Підпишіться на канали PostgreSQL NOTIFY через Server-Sent Events:

# Bearer-токен (JWT або API-токен)
curl -N "http://localhost:8080/db/my_database/sse?channels=orders,users" \
  -H "Authorization: Bearer $TOKEN"

# Прямі облікові дані (HTTP Basic Auth — GRANT … TO pgarachne не потрібен)
curl -N "http://localhost:8080/db/my_database/sse?channels=orders,users" \
  -u "alice:secret"

Кожне повідомлення — це JSON із назвою каналу та вмістом (payload):

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

Якщо вміст є звичайним текстом, він обгортається як рядок у data.

Канали не обмежені за роллю

На відміну від endpoint’ів JSON-RPC та MCP, SSE не застосовує SET LOCAL ROLE і жодним іншим чином не перевіряє права автентифікованої ролі перед підпискою. PgArachne автентифікує того, хто звертається (дійсний JWT, API-токен або прямі облікові дані для цільової бази даних), але будь-який автентифікований клієнт — незалежно від того, якій ролі відповідають його облікові дані — може підписатися на будь-який канал NOTIFY і отримуватиме все, що в ньому публікується. Це випливає з того, як побудований цей endpoint: усі SSE-клієнти для однієї бази даних спільно використовують одне з’єднання LISTEN, відкрите від імені сервісного облікового запису DB_USER, а сам PostgreSQL не має жодного GRANT на рівні каналу, якому можна було б делегувати права — канали LISTEN/NOTIFY не є об’єктами бази даних.

Не надсилайте через NOTIFY payload з даними, які не повинна бачити кожна автентифікована роль. Якщо вам потрібен контроль доступу на рівні каналу, реалізуйте його у власній логіці застосунку (наприклад, конвенції іменування каналів за роллю або фільтрацію вмісту payload) — PgArachne не зробить цього за вас на цьому endpoint’і.

Надсилання сповіщень з PostgreSQL

З psql або будь-якої іншої сесії бази даних:

-- Простий текстовий вміст
NOTIFY orders, 'new order';

-- JSON-вміст
NOTIFY orders, '{"id":123,"status":"created"}';

З тригера або збереженої процедури:

PERFORM pg_notify('orders', json_build_object('id', NEW.id, 'status', NEW.status)::text);
Примітка: NOTIFY доставляється іншим сесіям лише після того, як транзакція, що надсилає повідомлення, буде завершена (commit). Якщо ви виконуєте його всередині відкритої транзакції в psql, підписники не отримають повідомлення, доки ви не виконаєте COMMIT.