Streams: SSE and WebSocket
GuideDevelopersSince version 0.2.0
On this page
Streams are relayed without holding: each event arrives when the upstream emits it.
Product side: API gateway; operations side: SSE and WebSocket streams.
Server-sent events
curl -N -H "Authorization: Bearer $TOKEN" -H 'Accept: text/event-stream' https://api.example.com/events| Rule | Detail |
|---|---|
| No total deadline | An open stream is not cut by the operation's budget |
| Silence ends it | Past the operator's read timeout without a byte, the stream closes: have the upstream send a heartbeat (: ping) more often |
| Rate | Counted at opening |
A browser's EventSource cannot set Authorization. Read the stream with fetch:
const res = await fetch("https://api.example.com/events", {
headers: { Authorization: `Bearer ${token}`, Accept: "text/event-stream" },
});
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
for (;;) {
const { value, done } = await reader.read();
if (done) break;
handle(value); // split on the blank line that ends an event
}WebSocket
The upgrade is a request like any other: identity and rate are checked at opening, then the connection outlives the operation's budget.
// A browser sets no header on a WebSocket: the operator decides how the identity arrives (a cookie
// the contract declares, an edge that authenticates). A server-side client sets Authorization:
const ws = new WebSocket("wss://api.example.com/ws", { headers: { Authorization: `Bearer ${token}` } }); // Node (ws)A broker's event channels (acknowledgements, resumption) are described apart: asynchronous channels.