Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Real-Time & Events

The gateway supports real-time data through WebSocket subscriptions, live queries, and event triggers with webhook delivery.


WebSocket Subscriptions

Subscribe to table changes via WebSocket (backed by PostgreSQL LISTEN/NOTIFY):

const ws = new WebSocket('ws://localhost:8080/ws');
ws.send(JSON.stringify({
  type: 'subscribe',
  channel: 'qail_table_orders'
}));

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  // type: "subscribed" | "notification" | "error"
  console.log(msg);
};

Subscriptions are scoped by your RLS policies — each client only receives events for rows they are authorized to see.


Live Queries

Auto-refresh query results when underlying data changes:

ws.send(JSON.stringify({
  type: 'live_query',
  qail: "get orders where status = 'paid' order by created_at desc limit 10",
  table: 'orders',
  interval_ms: 2000
}));

The gateway re-executes the query at the specified interval and pushes updated results only when data has changed.


Event Triggers

Fire webhooks on database mutations. Define triggers in YAML:

- name: order_created
  table: orders
  operations: [create]
  webhook_url: "https://api.example.com/hooks/order-created"
  headers:
    X-Secret: webhook-secret-key
  retry_count: 3
- name: order_updated
  table: orders
  operations: [update]
  webhook_url: "https://api.example.com/hooks/order-updated"

Webhook Payload

{
  "trigger": "order_created",
  "table": "orders",
  "operation": "INSERT",
  "data": {
    "new": { "id": "uuid-...", "total": 150.00, "status": "pending" },
    "old": null
  },
  "timestamp": "2025-01-15T10:30:00Z"
}

Delivery Guarantees

  • Non-blocking: Webhooks fire asynchronously via tokio::spawn. The REST response is never delayed.
  • Retry with backoff: Failed deliveries retry with exponential backoff up to the configured count.
  • Custom headers: Attach secret keys or auth tokens to webhook requests.

Operations

Each trigger can fire on one or more operations:

OperationFires onPayload
createPOST /api/{table}new data
updatePATCH /api/{table}/:idnew + old data
deleteDELETE /api/{table}/:idold data

NDJSON Streaming

For large datasets, stream results as newline-delimited JSON:

GET /api/events?stream=true

Each row is sent as a separate JSON line with chunked transfer encoding — no buffering:

{"id":"uuid-1","type":"click","timestamp":"2025-01-01T00:00:00Z"}
{"id":"uuid-2","type":"purchase","timestamp":"2025-01-01T00:01:00Z"}
...

Ideal for data exports, ETL pipelines, and processing large tables without memory pressure.