Skip to content

Commit 7615536

Browse files
authored
Document using Server-sent Events with OpenAPI (#208)
Document using Server-sent Events with OpenAPI ### Motivation Inspired by #207. While OpenAPI doesn't provide extra support for Server-sent Events, it still makes sense to document what you can achieve today - turns out it's quite a lot. ### Modifications Documented how to spell an OpenAPI operation that returns SSE. ### Result Folks looking to use SSE can quickly see how to consume them (how to produce them would be a similar inverse process, left as an exercise to the reader.) ### Test Plan N/A Reviewed by: gjcairo Builds: ✔︎ pull request validation (5.8) - Build finished. ✔︎ pull request validation (5.9) - Build finished. ✔︎ pull request validation (docc test) - Build finished. ✔︎ pull request validation (integration test) - Build finished. ✔︎ pull request validation (nightly) - Build finished. ✔︎ pull request validation (soundness) - Build finished. #208
1 parent 269b31d commit 7615536

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

Sources/swift-openapi-generator/Documentation.docc/Articles/Useful-OpenAPI-patterns.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,56 @@ MyOpenOneOf:
7272
- #/components/schemas/Baz
7373
- type: object
7474
```
75+
76+
### Server-sent Events/EventSource
77+
78+
While [Server-sent Events](https://en.wikipedia.org/wiki/Server-sent_events) are not explicitly part of the OpenAPI 3.0 or 3.1 specification, you can document an operation that returns SSE and also the event payloads themselves.
79+
80+
> Important: Until [async bodies](https://github.com/apple/swift-openapi-generator/issues/9) are supported in Swift OpenAPI Generator, SSE are of limited value, as bodies are fully buffered before being returned to the caller.
81+
82+
In the OpenAPI document, an example of an operation that returns SSE could look like:
83+
84+
```yaml
85+
paths:
86+
/events:
87+
get:
88+
operationId: getEvents
89+
responses:
90+
'200':
91+
content:
92+
text/event-stream:
93+
schema:
94+
type: string
95+
format: binary
96+
components:
97+
schemas:
98+
MyEvent:
99+
type: object
100+
properties:
101+
...
102+
```
103+
104+
The returned binary body contains the raw events, and the stream can be split up into events by using one of the existing Swift implementations of Server-sent Events (sometimes libraries also use the term EventSource for the client of server-sent events).
105+
106+
If the event themselves are documented using one of the JSON schemas from the OpenAPI document (such as `MyEvent` in the example above), you can use the generated Codable type to easily parse the payload.
107+
108+
```swift
109+
guard case .ok(let okPayload) = try await client.getEvents(.init()) else {
110+
// handle an unexpected HTTP response code
111+
}
112+
guard case .text_event_hyphen_stream(let rawBody) = okPayload.body else {
113+
// handle an unexpected content type
114+
}
115+
// ... pass rawBody to an SSE library
116+
let streamOfRawEvents: AsyncSequence<Data> = ... // returned by an SSE library
117+
for try await rawEventData in streamOfRawEvents {
118+
let event = try JSONDecoder().decode(
119+
Components.Schemas.MyEvent.self
120+
from: rawEventData
121+
)
122+
// Print the type-safe event here
123+
print(event)
124+
}
125+
```
126+
127+
This way, with a little bit of manual work, you can still get type safety from an SSE operation being documented in an OpenAPI document.

0 commit comments

Comments
 (0)