-
Notifications
You must be signed in to change notification settings - Fork 9.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Streams in Responses #1576
Comments
@emmanuelproulx If you're talking about HTTP chunked encoding then this should be done through documenting the use of the |
Right. I understand. But there are times when you don't want to respond with JSON. As an example there's this standard REST API to retrieve images, IIIF ( http://iiif.io/ ) and it returns images not just JSON. I'd like to come up with a Swagger description of it but I don't know what to put in the 200 response. responses: Sure I could put a schema with type: string + format: binary there but in the end it'll keep the entire image in memory which for sure will blow up during performance testing. Anyway that's not how it's done normally in any API framework; they all use streams. There should be a way (not sure what the best way is) to specify that the returned entity is not JSON and should be treated as a stream. In OpenAPI 2 there was the "file" type that was used for that purpose but it's gone now. Would you have a good idea by any chance? |
If your content is If you do need one, it would have to be |
Yes, as I said, right now I'm using swagger-codegen and The alternative is to add a non-standard feature only in swagger-codegen, which is not ideal. |
@emmanuelproulx these are orthogonal concerns- the Media Type Object is just describing the response contents. Whether or not chunked encoding is used is set in |
@emmanuelproulx My recommendation in the past has been to use a stream by default and a byte array only if there is a maxlength defined. |
@darrelmiller why wouldn't this be indicated through headers? I'm apparently misunderstanding something here. |
@handrews You definitely can advertise that a server supports chunk encoding for a particular response using a header declaration. And I agree chunk-encoding and client side data representation are orthogonal concerns. If the OpenAPI description wants to hint to the client that the result can be stored in a fixed size byte array, then they should indicate that the response has a limited size using maxLength. Arguably, you can wait until you get the content-length response header until you allocate the byte array, but arguably HTTP responses are self descriptive so OpenAPI descriptions are optional in the first place :-). My perspective is that the current behaviour of the Swagger tools is less than optimal and they should default to a Stream datatype if the OpenAPI description doesn't limit the response size. |
@darrelmiller makes sense, thanks! |
We discussed this in the #1585 TSC meeting and the consensus was that tooling should interpret |
Are there any updates on this? The spec representation seems to be clarified, are we just waiting for updated tooling? |
@AtosNicoS that's my understanding. Unless you think something like raising a Technical Note or a blog posting would help clarify matters, then probably the way forward is raising issues on affected tools if they don't already exist, and referencing this issue. |
Hi, sorry to swoop in here, but say that there is an http stream of JSON, should that still be coded as |
@kylebevans Also, in OAS 3.1 uses the newer JSON Schema keywords
These apply to either |
@handrews thanks for such a detailed response. So to signal to a code generator to create stream processing code, I should write the spec to use a
I think I understand, but with this way then the user will have to write the JSON processing logic. I wish there was a way to model a stream of repeated objects with a content type and a delimiter. Thanks again for your help, though. I really appreciate it. |
@kylebevans well of course it depends on what your tooling supports. But at a glance this looks like the right approach for the header to me. If the response will always set the header to "chunked", I would add Are you using |
But keep in mind, with the multiple JSON documents thing, this is a limitation of HTTP and not simply OpenAPI. At some point, OAS cannot be expected to describe arbitrary application conventions across all media types. You could also get fancy and declare that your |
@handrews thank you so much for such detailed replies. Yes, it's multiple JSON documents in a neverending stream. It's actually twitter's streaming api that I'm trying to work with, and basically it's a persistent http connection that just keeps sending tweets in JSON like this forever:
Since it goes on forever, I don't think a multipart will work. However, I do think the array of strings of Twitter published an openapi spec for their v2 api (https://api.twitter.com/2/openapi.json), and they basically coded it as just one of the single objects instead of an array in a neverending stream. I was able to modify the generated code from openapi-generator (Go) to get streaming to work, but it was kind of a heavy mod, and i was hoping I could just fix the spec to get better generated code. Thanks so much for your help, you provided a lot of info, and I learned a lot about how to specify things with openapi. |
If I may offer an opinion:
Thus, the generated APIs should provide both options to the caller, fully parsed vs streamed access, regardless of the server's response. Whether to process as a stream or not, is really a coding/algorithm issue for the server and client to do, each independently; the fundamental protocol between them, is an octet stream. |
I think we have two issues here:
|
Another example of an API that sends a never ending stream of json objects (like the twitter api) is when you you watch Kubernetes resources. More details can be found at: This seems common enough that it should have a simple openapi way to describe it. |
I too would like json-lines with typed documents. Today the alternative is to implement pagination which is its own can of worms 🙈 |
Could this proposal work for streams of bytes? In it I propose adding: |
Note that there is now RFC 7464 JavaScript Object Notation (JSON) Text Sequences that defines With that in mind, is there anything that still needs to be clarified in the spec? I'm tagging things for a possible 3.0.4 release but I'm a little unclear on whether there's more to do here. |
Anything is streamable, in fact, the question is do we buffer it or not. I think it could be a framework/sdk option to threat contents as streams or buffer or at least, be streams per default and provide helpers to buffer them. From the OpenAPI point of view, I don't think it is needed to overweight the spec with those concerns. |
@darrelmiller I'm a bit confused on what does or does not need to be done with this issue. You made a comment about discussion in a TSC meeting about I'm trying to sort out various In #1544 (comment) I propose noting that |
I've filed:
|
PRs merged for 3.0.4, 3.1.1, and 3.2.0- closing! |
APIs that download binary data currently must be done by
type: string, format: binary
. This translates to byte arrays (in Java for example, anyway that's what swagger-ui and swagger-codegen do). But this consumes large amounts of memory if the data is very big, and easily gives out-of-memory errors.Typically huge blocks of data are sent via streams instead of byte arrays in most remote APIs. This allows for loading only a block of data at a time in memory.
The workaround used to be the '
file
' format but this was removed in version 3.What I propose is a new
type: stream
(format: binary
) which would allow this. As an example, this could map to Spring'sResponseEntity(inputStreamResource,...)
on the server side, and a okhttp'sResponseBody.byteStream()
on the client side. Lots of HTTP client & server frameworks support streams in API implementations so I'm surprised it doesn't already exist.The text was updated successfully, but these errors were encountered: