feat: add server-sent events endpoint for live updates #38

Closed
opened 2026-02-08 21:39:51 +00:00 by forbes · 0 comments
Owner

Summary

The spec lists /health and /ready but no push mechanism. The silo-mod client expects a live feed for real-time database activity updates (visible in the Selection View's "Database Activity" section).

Recommendation: SSE over WebSocket

SSE (text/event-stream) is simpler to implement in Go, works through nginx without upgrade headers, and matches the use case (server → client unidirectional push). WebSocket adds complexity for no benefit unless bidirectional communication is needed later.

Proposed endpoint

GET /api/events         (requires auth, viewer+)
Accept: text/event-stream

Event types

event: item.created
data: {"part_number":"A01-0002","description":"FILAMENT WINDING UNIT ASSY","item_type":"assembly"}

event: item.updated
data: {"part_number":"A01-0002","revision":3}

event: item.deleted
data: {"part_number":"A01-0002"}

event: revision.created
data: {"part_number":"A01-0002","revision_number":3,"comment":"Updated weight"}

event: server.state
data: {"mode":"normal"}

event: heartbeat
data: {}

Server implementation notes

  • Use Go's http.Flusher interface for SSE streaming
  • Track connected clients for /ready reporting
  • Broadcast item mutations from the existing handler layer (post-commit hook pattern)
  • Heartbeat every 30s to keep connection alive through proxies
  • Respect Last-Event-ID header for reconnection
  • Clean shutdown: close all SSE connections gracefully on SIGTERM

nginx config

location /api/events {
    proxy_pass http://silod_backend;
    proxy_buffering off;
    proxy_cache off;
    proxy_read_timeout 3600s;
    proxy_set_header Connection "";
    proxy_http_version 1.1;
}

Acceptance criteria

  • GET /api/events streams SSE with auth (viewer+)
  • Events emitted for item create/update/delete and revision creation
  • Heartbeat every 30s
  • /ready reports connected SSE client count
  • Last-Event-ID reconnection support
  • Endpoint added to spec Section 11.1
## Summary The spec lists `/health` and `/ready` but no push mechanism. The `silo-mod` client expects a live feed for real-time database activity updates (visible in the Selection View's "Database Activity" section). ## Recommendation: SSE over WebSocket SSE (`text/event-stream`) is simpler to implement in Go, works through nginx without upgrade headers, and matches the use case (server → client unidirectional push). WebSocket adds complexity for no benefit unless bidirectional communication is needed later. ## Proposed endpoint ``` GET /api/events (requires auth, viewer+) Accept: text/event-stream ``` ## Event types ``` event: item.created data: {"part_number":"A01-0002","description":"FILAMENT WINDING UNIT ASSY","item_type":"assembly"} event: item.updated data: {"part_number":"A01-0002","revision":3} event: item.deleted data: {"part_number":"A01-0002"} event: revision.created data: {"part_number":"A01-0002","revision_number":3,"comment":"Updated weight"} event: server.state data: {"mode":"normal"} event: heartbeat data: {} ``` ## Server implementation notes - Use Go's `http.Flusher` interface for SSE streaming - Track connected clients for `/ready` reporting - Broadcast item mutations from the existing handler layer (post-commit hook pattern) - Heartbeat every 30s to keep connection alive through proxies - Respect `Last-Event-ID` header for reconnection - Clean shutdown: close all SSE connections gracefully on SIGTERM ## nginx config ```nginx location /api/events { proxy_pass http://silod_backend; proxy_buffering off; proxy_cache off; proxy_read_timeout 3600s; proxy_set_header Connection ""; proxy_http_version 1.1; } ``` ## Acceptance criteria - [ ] `GET /api/events` streams SSE with auth (viewer+) - [ ] Events emitted for item create/update/delete and revision creation - [ ] Heartbeat every 30s - [ ] `/ready` reports connected SSE client count - [ ] `Last-Event-ID` reconnection support - [ ] Endpoint added to spec Section 11.1
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/silo#38