Support aborting requests via a Rack::Response#finish
I have a post endpoint where I'd like to conditionally return a custom Rack::Response, like so:
post do
if some_condition?
hash_of_contextually_relevant_goodness = { foo: 'bar' }
Rack::Response.new(
[hash_of_contextually_relevant_goodness],
418,
{ 'Content-Type' => 'application/json' }
).finish
else
# do some object creation stuff
end
end
However, this returns the following response body:
[
418,
{
"Content-Length": "13",
"Content-Type": "application/json"
},
{
"block": {},
"body": {
"block": null,
"body": [
"{:foo=>\"bar\"}"
],
"chunked": false,
"header": {
"Content-Length": "13",
"Content-Type": "application/json"
},
"length": 13,
"status": 418,
"writer": {}
},
"closed": false
}
]
It looks like the response is doubling up. What is the correct way to return a custom Rack::Response from my endpoint?
The problem is that it's going through a formatter. Before we figure out how to shortcut Grape in this case, I bet you can solve this by just doing status 418 and returning [hash_of...] as is. No?
Ah, fantastic! Yes, that totally works.
Thank you.
I've renamed this to "Support aborting requests via a Rack::Response.finish`, and labeled this as a feature. I am not sure we want this, but it's a valid thing.
Right, it seems like it would be "a valid thing". I kind of assumed you could just circumvent the Grape response with your own Rack::Response. However, your suggestion solves the one use case where I wanted to do this. I can't really think of another use case.
@dblock Would be good to Grape handle it. We have a use case where Grape works as a Gateway forwarding the request to another Service and having it like:
route :any, '*service_path' do
forward(request)
end
seems cleaner than:
route :any, '*service_path' do
response = forward(request)
response.headers.each { |k, v| header k, v }
status response.status
body response.body.first
end
I see, @danillos open to PRs.