Skip to content

Rack apps should return array #1041

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

Closed
lasseebert opened this issue Jun 22, 2015 · 13 comments
Closed

Rack apps should return array #1041

lasseebert opened this issue Jun 22, 2015 · 13 comments

Comments

@lasseebert
Copy link
Contributor

In this commit released with 0.12.0: 129ad6e, the formatter middleware now returns a Rack::Response and not an array.

From what I understand, this breaks Rack's conventions (and broke the middleware in my app).
Also, the docs for Rack::Response clearly states that an app should return Rack::Response#finish (aliased to #to_a).

Any reason this has been done?
If not, I will be happy to provide a pull request that reverses the commit ;)

@dblock
Copy link
Member

dblock commented Jun 22, 2015

This is in UPGRADING, and see #1029.

Rack spec (from what I remember after reading a lot of it :) just says you're supposed to return a Rack::Response or a "file-like object". With the change you describe above we are able to return a file stream. I couldn't find a single example where returning a Rack::Response itself would be an issue.

Are you seeing something broken or are you just worried about the convention?

@lasseebert
Copy link
Contributor Author

Thanks for the answer ;)
I didn't realize this was for streaming (and I didn't notice the UPGRADING untill now)

This broke a custom rack middleware in my app, because in some scenarios it will be just before the Formatter middleware.

If I need to make changes to the response before returning from my middleware, I must now first check if the response is an Array or a Rack::Response (The middleware is used in many different places).

If this is expected behavior, issue can be closed ;)

@dblock
Copy link
Member

dblock commented Jun 22, 2015

Yes, since UPGRADING documents this pretty thoroughly I think we're good. It's also easier to work with a Rack::Response in another middleware, you might want to consider adjusting all your code to that.

@dblock dblock closed this as completed Jun 22, 2015
@wagenet
Copy link
Contributor

wagenet commented Apr 20, 2016

@dblock sorry to reopen an old issue here. From what I can tell, the Rack API docs do imply that you should not return the Rack::Response itself from the app.call:

Your application's call should end returning Response#finish.

via http://www.rubydoc.info/github/rack/rack/Rack/Response

@wagenet
Copy link
Contributor

wagenet commented Apr 20, 2016

Also:

A Rack application is a Ruby object (not a class) that responds to call. It takes exactly one argument, the environment and returns an Array of exactly three values: The status, the headers, and the body.

http://www.rubydoc.info/github/rack/rack/master/file/SPEC

@dblock
Copy link
Member

dblock commented Apr 21, 2016

I just don't read it the same way I suppose. If we undo this the whole streaming thing doesn't work at all, no?

@wagenet
Copy link
Contributor

wagenet commented Apr 21, 2016

@dblock, I haven't read the code, but wouldn't you do streaming by having the third value of the array be a special object that responds to each? http://www.rubydoc.info/github/rack/rack/file/SPEC#The_Body

@dblock
Copy link
Member

dblock commented Apr 21, 2016

From what I understand that doesn't work because of how Rack treats this, but I could be totally wrong. Maybe @dan-corneanu can help us here?

@wagenet
Copy link
Contributor

wagenet commented Apr 21, 2016

@dblock yeah, I'm just reading the spec, might be things I'm missing. It looks like Rails is just doing something with Rack::Chunked::Body: https://github.com/rails/rails/blob/b6760d8f14af6b00250395f2c830b89e43621860/actionpack/lib/action_controller/metal/streaming.rb

@wagenet
Copy link
Contributor

wagenet commented Feb 28, 2018

@dblock ran across this again and I still believe that Grape's behavior here is incorrect.

@wagenet
Copy link
Contributor

wagenet commented Feb 28, 2018

I'm virtually certain that the correct approach for streaming is to return a body (the third array element in the response) that handles the streaming. The response from call should always be a simple array.

@dblock
Copy link
Member

dblock commented Mar 1, 2018

I am not sure what to do with this, I think you should raise a PR and we can look at the change?

@wagenet
Copy link
Contributor

wagenet commented Jan 14, 2020

@dblock With some recent changes to Rack it seems like this may not work correctly anymore as implicit destructuring is no longer supported: rack/rack@72959eb#diff-10b933d2c1fdc82ceecade456c64e1c2

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

No branches or pull requests

3 participants