Skip to content
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

Cannot use the openapi annotation with any of the rocket typed stream response types #68

Closed
ardouglas opened this issue Dec 8, 2021 · 4 comments

Comments

@ardouglas
Copy link

Hi,

Thank you so much for this library! It really is quite impressive what you have implemented thus far!

This issue is alluded to in #52 but I have observed that this seems to be a larger issue impacting all of the typed streams in rocket 0.5.0-rc.1. I hit the same issue mentioned in #52 but I saw that OpenApiResponderInner had already been implemented for TextStream<S>, ReaderStream<S>, and ByteStream<S so I decided to see if TextStream would work for my use case. The result is the same compiler error encountered with EventStream!:

error[E0562]: `impl Trait` not allowed outside of function and inherent method return types

The EventStream! and other typed streams return types ultimately expand to a type like the following and they trip up the openapi macro because it can't just reuse the type as defined.

impl rocket::futures::stream::Stream<Item = rocket::response::stream::Event>

I pulled your latest code and dug around a bit and made an attempt at a fix but I didn't see a clear path forward. In the case of TextStream and ByteStream, I could see where the openapi macro could rewrite the type to one of the string or byte representations that already have an implementation of OpenApiResponderInner. For EventStream, I was thinking along the same lines and tried rewriting the type as the rocket Event type; however, this type doesn't implement rocket::response::Responder so that looked like a dead end.

One alternative I was thinking might be possible would be to add an optional field to the openapi attribute that allows the developer to specify a type to substitute in place of the type that the typed stream macros expand to. I obviously don't have the same insight into the inner workings so this may be a terrible idea!

If you have some guidance on how you would like to see this functionality implemented I would be glad to take on this effort!

Thanks!

@lrodriguez14
Copy link

Hi @ralpha,

Unfortunately all the stream methods are not supported yet, any idea what could be missing for TextStream<S>, ReaderStream<S>, and ByteStream<S>?

@ralpha
Copy link
Collaborator

ralpha commented Mar 11, 2022

Hi @ralpha,

Unfortunately all the stream methods are not supported yet, any idea what could be missing for TextStream<S>, ReaderStream<S>, and ByteStream<S>?

These types should work:

With regards to the EventStream! and EventStream
Note that one is a macro, so this makes things more complicated. That is why I posted: #52 (comment)

The EventStream (struct) should be doable. But the Responder implementation is a bit special because of the generics
So this should be added here somewhere. https://github.com/GREsau/okapi/blob/master/rocket-okapi/src/response/responder_impls.rs#L302

I'll have a quick look if I can add that, but don't have that much time if it happens to be a bigger problem.

@ralpha ralpha closed this as completed in e686b44 Mar 11, 2022
@ralpha
Copy link
Collaborator

ralpha commented Mar 11, 2022

There, still took me still too long, but here is a fix. It is a somewhat dirty fix, but it works.
It had to so with EventStream<impl Stream<Item = Event>> (what the macro also creates)
The impl TYPE section is only allowed in return statements. And we are using the type like this:

let mut responses = <#return_type as ::rocket_okapi::response::OpenApiResponder>::responses(gen)?;

So that resulted in a compile error.
It now looks for the identifier (like EventStream) and if there is an impl statement and uses predefined types in that section.
This does not change the resulting docs. But because the filter is not incredible, the type has to be imported in the current module (use rocket::response::stream::EventStream;) in order to work.

We can always make this nicer in the future, but this at least gives you a fix.
Not going to create/ask for a new release on Crates.io. But you can use the master branch with the patch for the time being.

Created an example to test this and add some docs: https://github.com/GREsau/okapi/blob/master/examples/streams/src/main.rs

I also documented a way you can add undocumented endpoints in case it does not fit your needs or still have some errors because of special return types. (you can still report to error so we can fix it)

#[get("/undocumented_stream")]
async fn stream_one() -> std::io::Result<ReaderStream![File]> {
let file = File::open("README.md").await?;
Ok(ReaderStream::one(file))
}

// Skip Okapi parser to prevent compile errors.
.mount("/", rocket::routes![stream_one])

Let me know if this works for you.

@ralpha
Copy link
Collaborator

ralpha commented Mar 11, 2022

Please also note that RapiDoc and Swagger do not work well with infinite streams. So watch out when using the Try now buttons.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants