Summary
Add a WebSocket endpoint alongside the Connect RPC API for real-time document change subscriptions. This makes peat-node accessible from browsers, CLI tools, and lightweight integrations without any RPC client library.
Motivation
The Subscribe RPC is already server-streaming, but consuming it requires a Connect/gRPC client. A plain WebSocket endpoint streaming JSON would enable:
- Browser-based fleet dashboards with real-time updates (no gRPC-Web complexity)
- Simple CLI monitoring tools (
websocat ws://localhost:50051/ws/subscribe)
- Language-agnostic integrations that can open a WebSocket but don't have a Connect RPC library
- SSE (Server-Sent Events) as an alternative for HTTP/1.1-only environments
Proposed Design
WebSocket endpoint
GET /ws/subscribe?collections=platforms,commands
Upgrade: websocket
After upgrade, the server pushes JSON messages matching the DocumentChange proto schema:
{"collection":"platforms","docId":"alpha-agent","changeType":"CHANGE_TYPE_UPSERT","jsonData":"{...}"}
{"collection":"commands","docId":"cmd-1","changeType":"CHANGE_TYPE_UPSERT","jsonData":"{...}"}
Implementation
Since we're already using Axum (via connect-rust), adding WebSocket support is straightforward:
use axum::{extract::ws::WebSocket, routing::get};
let app = axum::Router::new()
.route("/ws/subscribe", get(ws_subscribe_handler))
.fallback_service(connect_router.into_axum_service());
The handler would:
- Accept query param
collections (comma-separated, empty = all)
- Upgrade to WebSocket
- Subscribe to the node's broadcast channel (same as the RPC Subscribe)
- Stream JSON-serialized DocumentChange messages
- Optionally accept client messages for dynamic filter changes
Optional: Server-Sent Events (SSE)
For environments where WebSocket isn't available (some proxies, HTTP/1.1 only):
GET /sse/subscribe?collections=platforms
Accept: text/event-stream
Axum supports SSE via axum::response::sse::Sse.
References
src/service.rs — existing subscribe() RPC implementation (broadcast channel → stream)
src/main.rs — Axum router setup (add WebSocket route alongside Connect RPC)
- connect-rust Axum integration already in place
Summary
Add a WebSocket endpoint alongside the Connect RPC API for real-time document change subscriptions. This makes peat-node accessible from browsers, CLI tools, and lightweight integrations without any RPC client library.
Motivation
The
SubscribeRPC is already server-streaming, but consuming it requires a Connect/gRPC client. A plain WebSocket endpoint streaming JSON would enable:websocat ws://localhost:50051/ws/subscribe)Proposed Design
WebSocket endpoint
After upgrade, the server pushes JSON messages matching the
DocumentChangeproto schema:{"collection":"platforms","docId":"alpha-agent","changeType":"CHANGE_TYPE_UPSERT","jsonData":"{...}"} {"collection":"commands","docId":"cmd-1","changeType":"CHANGE_TYPE_UPSERT","jsonData":"{...}"}Implementation
Since we're already using Axum (via connect-rust), adding WebSocket support is straightforward:
The handler would:
collections(comma-separated, empty = all)Optional: Server-Sent Events (SSE)
For environments where WebSocket isn't available (some proxies, HTTP/1.1 only):
Axum supports SSE via
axum::response::sse::Sse.References
src/service.rs— existingsubscribe()RPC implementation (broadcast channel → stream)src/main.rs— Axum router setup (add WebSocket route alongside Connect RPC)