You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -703,7 +703,7 @@ derived from `GenCodec` instance.
703
703
704
704
Ultimately, if you don't want to use `Future`s, you may replace it with some other asynchronous wrapper type,
705
705
e.g. Monix Task or some IO monad.
706
-
See [supporting result containers other than `Future`](#supporting-result-containers-other-than-future).
706
+
See [supporting result containers other than `Future`](#supporting-result-containers-other-than-future), [streaming serialization workflow](#streaming-serialization-workflow).
707
707
708
708
### Customizing serialization
709
709
@@ -1042,35 +1042,55 @@ When a client makes a request to a streaming endpoint:
1042
1042
1043
1043
This approach allows processing of potentially unlimited amounts of data with minimal memory footprint on both the client and server.
1044
1044
1045
-
### Streaming Types
1045
+
####Streaming response types
1046
1046
1047
-
Udash REST supports two main streaming content types:
1047
+
Streaming endpoints return data through a `StreamedRestResponse` instead of a regular `RestResponse`. This special
1048
+
response type contains a `StreamedBody` which delivers content incrementally, rather than all at once.
1048
1049
1049
-
1.**JSON Lists** - A stream of JSON objects sent as a JSON array `[{...}, {...}, ...]`
1050
-
2.**Raw Binary** - A stream of binary data chunks, for files or other binary content
1050
+
The framework supports two primary types of streaming responses:
1051
1051
1052
-
### Implementation Details
1052
+
1.**JSON Lists** - For streaming regular objects (any type `T` with a valid `RestSchema`), the content is delivered
1053
+
as a stream of JSON values with `application/json` content type. Each element in the `Observable` is serialized
1054
+
to JSON individually, allowing the client to process items as they arrive.
1053
1055
1054
-
- Under the hood, streaming is implemented using Monix `Observable`
1055
-
- Binary streams are transmitted as raw byte arrays
1056
-
- JSON streams are automatically serialized/deserialized between JSON and your data types
1057
-
- The server can control batch size to optimize network usage versus memory consumption
1056
+
2.**Binary Streams** - For streaming binary data (`Observable[Array[Byte]]`), the content is delivered as a raw binary
1057
+
stream with `application/octet-stream` content type. This is particularly useful for large file downloads or
1058
+
real-time binary data processing.
1058
1059
1059
-
###Handling Large Response Collections
1060
+
#### Streaming serialization workflow
1060
1061
1061
-
When dealing with large collections, streaming is preferable to loading everything in memory:
1062
+
When a method returns an `Observable[T]`, the serialization flow is:
1062
1063
1063
-
```scala
1064
-
// Without streaming - entire list is loaded in memory
1065
-
defgetAllItems():Future[List[Item]]
1064
+
1. Each element of type `T` is serialized using the appropriate `AsRaw[JsonValue, T]` instance
1065
+
2. These elements are delivered incrementally as part of a `StreamedBody.JsonList`
1066
+
3. The client can process the items as they arrive, without waiting for the entire stream to complete
1067
+
1068
+
For binary data (`Observable[Array[Byte]]`), each byte array chunk is directly sent through a `StreamedBody.RawBinary`
1069
+
without additional transformation.
1070
+
1071
+
#### Customizing streaming serialization
1066
1072
1067
-
// With streaming - items are processed incrementally
1068
-
defstreamAllItems():Observable[Item]
1073
+
Just as with regular responses, you can customize how streaming responses are serialized. For instance, you might want
1074
+
to provide a custom instance of `AsRaw[StreamedBody, Observable[T]]` for a specific type:
1075
+
1076
+
```scala
1077
+
// Custom serialization for streaming a specialized data type
This approach allows you to include additional metadata or context with your streams while maintaining the streaming behavior.
1185
+
1096
1186
## Generating OpenAPI 3.0 specifications
1097
1187
1098
1188
[OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md) is an open standard for describing
@@ -1388,7 +1478,88 @@ Because multiple REST HTTP methods may have the same path, adjusters are collect
1388
1478
are applied on the associated Path Item Object. When path item adjuster is applied on a [prefix method](#prefix-methods),
1389
1479
it will apply to all Path Item Objects associated with result of this prefix method.
1390
1480
1481
+
### OpenAPI for Streaming Endpoints
1482
+
1483
+
When using Udash REST's streaming capabilities, OpenAPI specifications are automatically generated to reflect the streaming nature of the endpoints. This section describes how streaming responses are represented in OpenAPI documents.
1484
+
1485
+
#### Streaming Response Schema
1486
+
1487
+
Methods that return `Observable[T]` are automatically recognized as streaming endpoints. In the generated OpenAPI document, these endpoints are represented as arrays of the type `T`:
1488
+
1489
+
```scala
1490
+
traitStreamingApi {
1491
+
// This will be documented as an array of Item in OpenAPI
1492
+
defstreamItems(filter: String):Observable[Item]
1493
+
}
1494
+
```
1495
+
1496
+
For a streaming endpoint returning `Observable[Item]`, the generated schema will represent this as an array of `Item` objects. The framework automatically wraps the element type in an array schema to indicate that multiple items may be delivered over time.
1497
+
1498
+
#### Supported Streaming Formats
1499
+
1500
+
The OpenAPI document correctly describes the available media types for streaming responses:
1501
+
1502
+
1.**JSON Lists** - When streaming regular objects, they're represented as a JSON array in the schema.
1503
+
This is reflected in the OpenAPI document with content type `application/json`.
1504
+
1505
+
2.**Binary Streams** - When streaming `Array[Byte]` (binary data), the content type in the OpenAPI document
1506
+
will be `application/octet-stream`.
1507
+
1508
+
Example schema representation for a streaming endpoint:
1509
+
1510
+
```json
1511
+
{
1512
+
"paths": {
1513
+
"/streamItems": {
1514
+
"get": {
1515
+
"responses": {
1516
+
"200": {
1517
+
"description": "Success",
1518
+
"content": {
1519
+
"application/json": {
1520
+
"schema": {
1521
+
"type": "array",
1522
+
"items": {
1523
+
"$ref": "#/components/schemas/Item"
1524
+
}
1525
+
}
1526
+
}
1527
+
}
1528
+
}
1529
+
}
1530
+
}
1531
+
}
1532
+
}
1533
+
}
1534
+
```
1535
+
1536
+
#### Customizing OpenAPI for Streaming Endpoints
1537
+
1538
+
You can use the same annotation-based customization mechanisms discussed earlier to modify the OpenAPI documentation for streaming endpoints:
1539
+
1540
+
```scala
1541
+
traitStreamingApi {
1542
+
@description("Streams items matching the filter criteria")
1543
+
@adjustOperation(op => op.copy(
1544
+
responses = op.responses.copy(
1545
+
byStatusCode = op.responses.byStatusCode + (
1546
+
200->RefOr(Response(
1547
+
description ="A stream of matching items that may be processed incrementally",
- While the OpenAPI specification doesn't have native support for true streaming semantics, Udash REST represents streaming endpoints as array responses. This is the most accurate representation within the constraints of the OpenAPI specification format. Consumers of your API should understand that these array responses may be delivered incrementally rather than all at once, especially for potentially large datasets.
0 commit comments