Skip to content

Commit

Permalink
Add api_format function accessible from inside_route
Browse files Browse the repository at this point in the history
fetch_formatter will look api.format first
Use fetch {} instead of [] ||
Update spec
Add HTTP_VERSION in Grape::Http::Headers
Update README
  • Loading branch information
ericproulx committed Oct 20, 2024
1 parent 277fe3e commit 3fc99b1
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 6 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3066,15 +3066,15 @@ end
* `GET /hello.xls` with an `Accept: application/xml` header has an unrecognized extension, but the `Accept` header corresponds to a recognized format, so it will respond with XML.
* `GET /hello.xls` with an `Accept: text/plain` header has an unrecognized extension *and* an unrecognized `Accept` header, so it will respond with JSON (the default format).

You can override this process explicitly by specifying `env['api.format']` in the API itself.
You can override this process explicitly by calling `api_format` in the API itself.
For example, the following API will let you upload arbitrary files and return their contents as an attachment with the correct MIME type.

```ruby
class Twitter::API < Grape::API
post 'attachment' do
filename = params[:file][:filename]
content_type MIME::Types.type_for(filename)[0].to_s
env['api.format'] = :binary # there's no formatter for :binary, data will be returned "as is"
api_format :binary # there's no formatter for :binary, data will be returned "as is"
header 'Content-Disposition', "attachment; filename*=UTF-8''#{CGI.escape(filename)}"
params[:file][:tempfile].read
end
Expand Down
6 changes: 5 additions & 1 deletion lib/grape/dsl/inside_route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,11 @@ def entity_representation_for(entity_class, object, options)
end

def http_version
env['HTTP_VERSION'] || env[Rack::SERVER_PROTOCOL]
env.fetch(Grape::Http::Headers::HTTP_VERSION) { env[Rack::SERVER_PROTOCOL] }
end

def api_format(format)
env[Grape::Env::API_FORMAT] = format
end

def context
Expand Down
1 change: 1 addition & 0 deletions lib/grape/http/headers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Headers
HTTP_ACCEPT_VERSION = 'HTTP_ACCEPT_VERSION'
HTTP_ACCEPT = 'HTTP_ACCEPT'
HTTP_TRANSFER_ENCODING = 'HTTP_TRANSFER_ENCODING'
HTTP_VERSION = 'HTTP_VERSION'

ALLOW = 'Allow'
LOCATION = 'Location'
Expand Down
2 changes: 1 addition & 1 deletion lib/grape/middleware/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def build_formatted_response(status, headers, bodies)
end

def fetch_formatter(headers, options)
api_format = mime_types[headers[Rack::CONTENT_TYPE]] || env[Grape::Env::API_FORMAT]
api_format = env.fetch(Grape::Env::API_FORMAT) { mime_types[headers[Rack::CONTENT_TYPE]] }
Grape::Formatter.formatter_for(api_format, options[:formatters])
end

Expand Down
4 changes: 2 additions & 2 deletions spec/grape/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4092,9 +4092,9 @@ def my_method
expect(last_response.body).to eq({ meaning_of_life: 42 }.to_json)
end

it 'can be overwritten with an explicit content type' do
it 'can be overwritten with an explicit api_format' do
subject.get '/meaning_of_life_with_content_type' do
content_type 'text/plain'
api_format 'text/plain'
{ meaning_of_life: 42 }.to_s
end
get '/meaning_of_life_with_content_type'
Expand Down

0 comments on commit 3fc99b1

Please sign in to comment.