Design discussion: smithy-lang/smithy#3221 (core repo) — that's where the cross-language protocol design is being settled. This issue tracks the TypeScript implementation.
Smithy models event streams with @streaming unions, and the only wire framing today is the binary application/vnd.amazon.eventstream encoding. A growing class of services — LLM/agent APIs, MCP servers, anything a browser consumes with EventSource — stream over Server-Sent Events (text/event-stream) instead. A Smithy model can't describe that today, so teams drop out of Smithy for streaming endpoints and hand-write them.
SSE isn't a new streaming model — it's an alternative framing of the event streams Smithy already has. The typed union, the generated AsyncIterable, and the per-event serde are reusable unchanged; in smithy-typescript, framing is fully encapsulated behind the EventStreamMarshaller interface, so an SSE implementation is a drop-in alternate marshaller plus a protocol that selects it. No Smithy implementation currently offers SSE as an event-stream protocol (smithy-java handles text/event-stream only inside its MCP proxy, not as a modeled protocol), so this would be new across the ecosystem — which is why the trait design is worth settling up front.
I've built a working end-to-end prototype (PR to follow): an SseEventStreamMarshaller with the same contract as the binary one, a seam for protocols to pick their marshaller, and an experimental sseJson protocol gated behind an experimentalSseProtocol smithy-build flag so nothing changes for existing consumers.
Questions for maintainers:
- Does SSE belong in Smithy as an official protocol, and should the trait live in smithy-lang/smithy (cross-language) or start TypeScript-only?
- Trait shape: standalone
sseJson-style protocol, or a modifier composing with existing HTTP protocols?
- Wire mapping: is
event: = Smithy event-type name right? How should modeled exceptions and $unknown be represented?
Happy to adapt the prototype to whatever shape maintainers prefer.
Design discussion: smithy-lang/smithy#3221 (core repo) — that's where the cross-language protocol design is being settled. This issue tracks the TypeScript implementation.
Smithy models event streams with
@streamingunions, and the only wire framing today is the binaryapplication/vnd.amazon.eventstreamencoding. A growing class of services — LLM/agent APIs, MCP servers, anything a browser consumes withEventSource— stream over Server-Sent Events (text/event-stream) instead. A Smithy model can't describe that today, so teams drop out of Smithy for streaming endpoints and hand-write them.SSE isn't a new streaming model — it's an alternative framing of the event streams Smithy already has. The typed union, the generated
AsyncIterable, and the per-event serde are reusable unchanged; in smithy-typescript, framing is fully encapsulated behind theEventStreamMarshallerinterface, so an SSE implementation is a drop-in alternate marshaller plus a protocol that selects it. No Smithy implementation currently offers SSE as an event-stream protocol (smithy-java handlestext/event-streamonly inside its MCP proxy, not as a modeled protocol), so this would be new across the ecosystem — which is why the trait design is worth settling up front.I've built a working end-to-end prototype (PR to follow): an
SseEventStreamMarshallerwith the same contract as the binary one, a seam for protocols to pick their marshaller, and an experimentalsseJsonprotocol gated behind anexperimentalSseProtocolsmithy-build flag so nothing changes for existing consumers.Questions for maintainers:
sseJson-style protocol, or a modifier composing with existing HTTP protocols?event:= Smithy event-type name right? How should modeled exceptions and$unknownbe represented?Happy to adapt the prototype to whatever shape maintainers prefer.