Skip to content

Realtime

Snaapi supports realtime event streaming via Server-Sent Events (SSE). Connect to the stream endpoint to receive filtered, permission-aware events as they happen.

SSE Streaming

Server-Sent Events provide a one-way, persistent connection from the server to the client. Events are streamed over HTTP with automatic reconnection support built into the browser's EventSource API.

Response Headers

Header Value
Content-Type text/event-stream
Cache-Control no-cache
Connection keep-alive
X-Accel-Buffering no

Stream Endpoint

GET /stream/{resourceName}

Requires authentication. The authenticated user's permissions determine which events and fields are visible.

Query Parameters

Parameter Type Default Description
events string created,updated,deleted Comma-separated event types to subscribe to
fields string All allowed fields Comma-separated field names to include

Examples

Subscribe to all events for a resource:

GET /stream/posts

Subscribe to only created and updated events:

GET /stream/posts?events=created,updated

Subscribe with specific fields:

GET /stream/posts?events=created&fields=title,author_id

Event Filtering

Event Type Filtering

Use the events query parameter to subscribe to specific event types. Valid values are created, updated, and deleted.

Field Filtering

Use the fields query parameter to limit which fields appear in the event data. The following rules apply:

  • Requested fields are intersected with the user's allowed fields (from permissions)
  • System fields (id, created_at, updated_at) are always included
  • The changes arrays in event data are updated to reflect only filtered fields

Permission-Based Filtering

Events are filtered based on the authenticated user's read permissions:

  • Only events matching the user's filter constraints are delivered
  • Only fields the user has permission to read are included
  • Filter operators applied: eq, neq, in, nin, gt, gte, lt, lte, is_null, is_not_null, like, ilike, regex, iregex, similar

Connection Lifecycle

1. Connection Established

The client connects with authentication credentials. On success, the server sends an initial message:

retry: 3000
: connected

The retry: 3000 directive tells the client to wait 3 seconds before attempting to reconnect if the connection drops.

2. Heartbeat

The server sends a heartbeat comment every 30 seconds to keep the connection alive and detect disconnects:

: heartbeat

3. Event Delivery

When a matching event occurs, it is streamed in SSE format:

event: posts.created
data: {"old":null,"new":{"id":"abc-123","title":"Hello"},"changes":{"added":["id","title"],"updated":[],"removed":[]}}
id: event-uuid
retry: 3000
SSE Field Description
event Event type (e.g., posts.created)
data JSON-encoded event data (old/new/changes)
id Event UUID (used for reconnection resumption)
retry Reconnection delay in milliseconds

4. Disconnection

When the client disconnects (network drop, tab close, explicit close):

  • The server detects the disconnection
  • The connection is unsubscribed from the EventBroadcaster
  • Resources are cleaned up automatically

Client Example

const eventSource = new EventSource("/stream/posts", {
  headers: { Authorization: "Bearer <token>" },
});

eventSource.addEventListener("posts.created", (event) => {
  const data = JSON.parse(event.data);
  console.log("New post:", data.new);
});

eventSource.addEventListener("posts.updated", (event) => {
  const data = JSON.parse(event.data);
  console.log("Updated:", data.changes.updated);
});

eventSource.onerror = () => {
  console.log("Connection lost, reconnecting...");
};