From 76155366d2d934b65eeae40ebf9d30516ffb34b8 Mon Sep 17 00:00:00 2001 From: Honza Dvorsky Date: Thu, 17 Aug 2023 18:53:59 +0200 Subject: [PATCH] Document using Server-sent Events with OpenAPI (#208) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document using Server-sent Events with OpenAPI ### Motivation Inspired by https://github.com/apple/swift-openapi-generator/issues/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. https://github.com/apple/swift-openapi-generator/pull/208 --- .../Articles/Useful-OpenAPI-patterns.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Sources/swift-openapi-generator/Documentation.docc/Articles/Useful-OpenAPI-patterns.md b/Sources/swift-openapi-generator/Documentation.docc/Articles/Useful-OpenAPI-patterns.md index 358bf066..20e764fe 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Articles/Useful-OpenAPI-patterns.md +++ b/Sources/swift-openapi-generator/Documentation.docc/Articles/Useful-OpenAPI-patterns.md @@ -72,3 +72,56 @@ MyOpenOneOf: - #/components/schemas/Baz - type: object ``` + +### Server-sent Events/EventSource + +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. + +> 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. + +In the OpenAPI document, an example of an operation that returns SSE could look like: + +```yaml +paths: + /events: + get: + operationId: getEvents + responses: + '200': + content: + text/event-stream: + schema: + type: string + format: binary +components: + schemas: + MyEvent: + type: object + properties: + ... +``` + +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). + +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. + +```swift +guard case .ok(let okPayload) = try await client.getEvents(.init()) else { + // handle an unexpected HTTP response code +} +guard case .text_event_hyphen_stream(let rawBody) = okPayload.body else { + // handle an unexpected content type +} +// ... pass rawBody to an SSE library +let streamOfRawEvents: AsyncSequence = ... // returned by an SSE library +for try await rawEventData in streamOfRawEvents { + let event = try JSONDecoder().decode( + Components.Schemas.MyEvent.self + from: rawEventData + ) + // Print the type-safe event here + print(event) +} +``` + +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.