docs: Server-Sent Events how-to + built-in SSE marshaler references#91
docs: Server-Sent Events how-to + built-in SSE marshaler references#91ankurs wants to merge 2 commits into
Conversation
Adds howto/server-sent-events.md as a dedicated page for browser-consumable streaming over the gateway — covers wire format, EventSource and curl usage, handler patterns for AI/LLM workloads (context cancellation, TTFT), opt-out via DISABLE_SSE_MARSHALER, custom marshaler registration, and common pitfalls (compression, proxy buffering, EventSource GET-only, gateway message wrapping). Updates cross-cutting pages: - config-reference.md gains a DISABLE_SSE_MARSHALER row in HTTP Gateway. - streaming-rpcs.md gateway section now lists SSE as a default behaviour alongside NDJSON, with a Related link to the new page. - gateway-extensions.md built-ins list calls out the auto-registered text/event-stream marshaler and how to override it. Nav order shifts: server-sent-events at 22, database/cache/messaging bumped one each. Playwright pages.ts updated to match.
|
Warning Review limit reached
More reviews will be available in 57 minutes and 48 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds documentation for ColdBrew’s built-in Server-Sent Events (SSE) gateway marshaler (Accept-driven text/event-stream), including a new how-to page and cross-references from related docs, plus updates to Playwright’s How To page list and nav ordering.
Changes:
- Add a new
howto/server-sent-events.mdpage covering SSE framing, client examples, operational pitfalls, and customization/opt-out (DISABLE_SSE_MARSHALER). - Update streaming and gateway-extension docs to mention SSE as a first-class gateway streaming shape and link to the new guide.
- Update config reference and test page lists to include the new page and adjusted How To sidebar ordering.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/pages.ts | Inserts the new SSE how-to page into allHowtoPages in nav order. |
| howto/streaming-rpcs.md | Documents SSE as an alternative server-streaming HTTP shape and links to the new how-to. |
| howto/server-sent-events.md | New end-to-end SSE how-to documentation (wire format, clients, ops pitfalls, customization). |
| howto/messaging.md | Bumps nav_order to keep sidebar ordering consistent after inserting SSE. |
| howto/gateway-extensions.md | Mentions the built-in SSE marshaler and links to the SSE how-to. |
| howto/database.md | Bumps nav_order to keep sidebar ordering consistent after inserting SSE. |
| howto/cache.md | Bumps nav_order to keep sidebar ordering consistent after inserting SSE. |
| config-reference.md | Adds DISABLE_SSE_MARSHALER to the HTTP Gateway config table. |
Comments suppressed due to low confidence (1)
howto/server-sent-events.md:58
- The proto example exposes the stream as
post: "/api/v1/stream/tokens", but the immediately-following browserEventSourceexample calls the same path (andEventSourcecan onlyGET). To keep the examples consistent, either add a GET mapping in the proto snippet, or update the browser section to demonstrate a POST-capable SSE client instead ofEventSourcefor this endpoint.
```protobuf
rpc StreamTokens(StreamTokensRequest) returns (stream Token) {
option (google.api.http) = {
post: "/api/v1/stream/tokens"
body: "*"
};
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| Practical things to know: | ||
|
|
||
| - **Server-Sent Events work out of the box.** ColdBrew registers a `text/event-stream` marshaler by default so any server-streaming RPC is consumable by a browser `EventSource(...)` without extra code. See [Server-Sent Events](/howto/server-sent-events/) for the framing, opt-out, and AI/LLM patterns; set `DISABLE_SSE_MARSHALER=true` to suppress. |
There was a problem hiding this comment.
Fixed in fc41c0d: the SSE bullet now explicitly notes that browser EventSource only works for endpoints exposed via HTTP GET, and points POST-mapped streams at fetch + microsoft/fetch-event-source (the wire format is identical either way).
|
|
||
| --- | ||
|
|
||
| ColdBrew exposes every server-streaming gRPC method as Server-Sent Events for free. A browser `EventSource(...)` can consume any `rpc Foo(Req) returns (stream Resp)` endpoint directly — no per-service wiring, no proto changes, no custom HTTP handler. This is the path of least resistance for AI/LLM token streams, progress feeds, change notifications, and any other server → client push that benefits from staying on plain HTTP. |
There was a problem hiding this comment.
Fixed in fc41c0d. The intro now says "any rpc Foo(Req) returns (stream Resp) endpoint is SSE-consumable when the client sends Accept: text/event-stream" (without the EventSource framing) and adds a separate paragraph explaining that EventSource itself is GET-only, with the fetch / fetch-event-source workaround for POST-mapped streams. The duplicate caveat in the Browser EventSource section is tightened to a single back-reference.
| | `DISABLE_DEBUG` | bool | `false` | Disable pprof debug endpoints at `/debug/` | | ||
| | `USE_JSON_BUILTIN_MARSHALLER` | bool | `false` | Use `encoding/json` instead of the default protojson marshaller for `application/json` | | ||
| | `JSON_BUILTIN_MARSHALLER_MIME` | string | `application/json` | Content-Type for the JSON builtin marshaller | | ||
| | `DISABLE_SSE_MARSHALER` | bool | `false` | Disable the auto-registered `text/event-stream` marshaler. When `false` (default), server-streaming RPCs are consumable as Server-Sent Events by clients that send `Accept: text/event-stream` — see [Server-Sent Events](/howto/server-sent-events/) | |
There was a problem hiding this comment.
Skipping in this PR — the inconsistency is at the env-var level in core: DISABLE_SSE_MARSHALER uses single-l (matches the Go type SSEMarshaler), while USE_JSON_BUILTIN_MARSHALLER uses double-l. My row matches its env var; the existing rows match theirs. Editing the docs to use one spelling everywhere would misrepresent the actual variable name. The right fix is to standardize the env-var spelling in core in a separate change (it would be a breaking env-var rename, so worth its own discussion).
| ## Related | ||
|
|
||
| - [Streaming RPCs](/howto/streaming-rpcs/) — Proto definitions, handler patterns, deadline propagation, and the gateway's behavior for every gRPC method shape. | ||
| - [HTTP Gateway Extensions](/howto/gateway-extensions/) — Registering custom marshalers, error handlers, middleware, and additional routes on the gateway. | ||
| - [Configuration Reference](/config-reference/) — `DISABLE_SSE_MARSHALER` and related HTTP gateway options. | ||
| - [Metrics](/howto/Metrics/) — Where to surface TTFT and per-stream counters alongside ColdBrew's default Prometheus metrics. |
There was a problem hiding this comment.
Fixed in fc41c0d — added a row to howto/index.md under Build: "Stream tokens to the browser (AI/LLM, progress feeds) → Server-Sent Events", next to the Streaming RPCs entry.
| - The incoming-header matcher derived from `HTTP_HEADER_PREFIXES` | ||
| - Marshalers for `application/proto` and `application/protobuf` | ||
| - The internal `spanRouteMiddleware` (sets the OTEL span name + `http.route` attribute) | ||
| - A `text/event-stream` marshaler (`core.SSEMarshaler`) so server-streaming RPCs are browser `EventSource`-consumable out of the box. Set `DISABLE_SSE_MARSHALER=true` to suppress, or register your own marshaler for `text/event-stream` to override the default. See [Server-Sent Events](/howto/server-sent-events/) for the framing details |
Addresses review feedback on the SSE docs: - streaming-rpcs.md and server-sent-events.md now explicitly note that browser EventSource is GET-only, with a pointer to fetch + microsoft/fetch-event-source for POST-mapped streams. The wire format is identical either way; only the request side changes. - The proto example in server-sent-events.md maps to GET instead of POST so the EventSource example below it works as-is. POST mapping is mentioned inline as an alternative. - The curl examples use the GET form to match. POST variant is documented as a one-line tweak. - Adds a row for "Server-Sent Events" to howto/index.md for discoverability. - Fills in the trailing period on the new SSE bullet in gateway-extensions.md.
Summary
Documents the auto-registered SSE marshaler shipped in core#92, which makes every server-streaming gateway RPC browser-
EventSource-consumable out of the box.New page —
howto/server-sent-events.md:data: <json>\n\n) + the gateway{"result": ...}wrapping behaviour.EventSourceand curl examples (covers the GET-only browser API caveat and themicrosoft/fetch-event-sourceworkaround for POST streams).OutcomeCanceled.DISABLE_SSE_MARSHALER=true, plus how to register a customtext/event-streammarshaler that wins over the default.Cross-cutting updates:
config-reference.md—DISABLE_SSE_MARSHALERrow added in the HTTP Gateway section.howto/streaming-rpcs.md— gateway-shape table now lists SSE alongside NDJSON; a new bullet calls out the default behaviour and links to the new page; Related section gains the cross-link.howto/gateway-extensions.md— built-ins list mentions the auto-registeredtext/event-streammarshaler and the override path.Nav + tests:
nav_order: 22forserver-sent-events.md; database/cache/messaging each bumped by one (now 23/24/25) to keep streaming and SSE adjacent in the sidebar.tests/pages.tsupdated to match.Test plan
cd docs.coldbrew.cloud && bundle exec jekyll serve— verify the new page renders, nav order is correct, internal links resolve.npx playwright testagainst a local Jekyll server —tests/navigation.spec.tswalks every entry inallHowtoPagesand asserts a 200 + visible heading on each, so the new page is covered automatically./howto/streaming-rpcs/→/howto/server-sent-events/, and vice versa;/howto/gateway-extensions/and/config-reference/both link to the new page.