Skip to content

Use proper .format suffix if you have one path, issue 965 #1001

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

Merged
merged 1 commit into from
Apr 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* [#988](https://github.com/intridea/grape/pull/988): Fixed duplicate identical endpoints - [@u2](https://github.com/u2).
* [#936](https://github.com/intridea/grape/pull/936): Fixed default params processing for optional groups - [@dm1try](https://github.com/dm1try).
* [#942](https://github.com/intridea/grape/pull/942): Fixed forced presence for optional params when based on a reused entity that was also required in another context - [@croeck](https://github.com/croeck).
* [#1001](https://github.com/intridea/grape/pull/1001): Fixed calling endpoint with specified format with format in its path - [@hodak](https://github.com/hodak).

* Your contribution here.

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1680,7 +1680,7 @@ end
```

You can have your API only respond to a single format with `format`. If you use this, the API will **not** respond to file
extensions. For example, consider the following API.
extensions other than specified in `format`. For example, consider the following API.

```ruby
class SingleFormatAPI < Grape::API
Expand All @@ -1693,7 +1693,8 @@ end
```

* `GET /hello` will respond with JSON.
* `GET /hello.xml`, `GET /hello.json`, `GET /hello.foobar`, or *any* other extension will respond with an HTTP 404 error code.
* `GET /hello.json` will respond with JSON.
* `GET /hello.xml`, `GET /hello.foobar`, or *any* other extension will respond with an HTTP 404 error code.
* `GET /hello?format=xml` will respond with an HTTP 406 error code, because the XML format specified by the request parameter
is not supported.
* `GET /hello` with an `Accept: application/xml` header will still respond with JSON, since it could not negotiate a
Expand Down
20 changes: 20 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ error!(e)

See [#889](https://github.com/intridea/grape/issues/889) for more information.

#### Changes to routes when using `format`

Now it's possible to call API with proper suffix when single `format` is defined. I. e.

```ruby
class API < Grape::API
format :json

get :hello do
{ hello: 'world' }
end
end
```

Will respond with JSON to `/hello` **and** `/hello.json`.

Will respond with 404 to `/hello.xml`, `/hello.txt` etc.

See the [#1001](https://github.com/intridea/grape/pull/1001) for more info.

### Upgrading to >= 0.11.0

#### Added Rack 1.6.0 support
Expand Down
2 changes: 1 addition & 1 deletion lib/grape/path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def has_path?

def suffix
if uses_specific_format?
''
"(.#{settings[:format]})"
elsif !uses_path_versioning? || (has_namespace? || has_path?)
'(.:format)'
else
Expand Down
56 changes: 56 additions & 0 deletions spec/grape/api/deeply_included_options_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require 'spec_helper'

module API
module Defaults
extend ActiveSupport::Concern
included do
format :json
end
end

module Admin
module Defaults
extend ActiveSupport::Concern
include API::Defaults
end

class Users < Grape::API
include API::Admin::Defaults

resource :users do
get do
status 200
end
end
end
end
end

class Main < Grape::API
mount API::Admin::Users
end

describe Grape::API do
subject { Main }

def app
subject
end

it 'works for unspecified format' do
get '/users'
expect(last_response.status).to eql 200
expect(last_response.content_type).to eql 'application/json'
end

it 'works for specified format' do
get '/users.json'
expect(last_response.status).to eql 200
expect(last_response.content_type).to eql 'application/json'
end

it "doesn't work for format different than specified" do
get '/users.txt'
expect(last_response.status).to eql 404
end
end
10 changes: 8 additions & 2 deletions spec/grape/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -804,14 +804,16 @@ def subject.enable_root_route!
it 'sets content type for json error' do
subject.format :json
subject.get('/error') { error!('error in json', 500) }
get '/error'
get '/error.json'
expect(last_response.status).to eql 500
expect(last_response.headers['Content-Type']).to eql 'application/json'
end

it 'sets content type for xml error' do
subject.format :xml
subject.get('/error') { error!('error in xml', 500) }
get '/error'
expect(last_response.status).to eql 500
expect(last_response.headers['Content-Type']).to eql 'application/xml'
end

Expand Down Expand Up @@ -2642,7 +2644,11 @@ def static
get '/meaning_of_life'
expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s)
end
it 'does not accept any extensions' do
it 'accepts specified extension' do
get '/meaning_of_life.txt'
expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s)
end
it 'does not accept extensions other than specified' do
get '/meaning_of_life.json'
expect(last_response.status).to eq(404)
end
Expand Down
10 changes: 6 additions & 4 deletions spec/grape/path_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,12 @@ module Grape

describe '#suffix' do
context 'when using a specific format' do
it 'is empty' do
it 'accepts specified format' do
path = Path.new(nil, nil, {})
allow(path).to receive(:uses_specific_format?) { true }
allow(path).to receive(:settings) { { format: :json } }

expect(path.suffix).to eql('')
expect(path.suffix).to eql('(.json)')
end
end

Expand Down Expand Up @@ -237,12 +238,13 @@ module Grape
end

context 'when using a specific format' do
it 'does not have a suffix' do
it 'might have a suffix with specified format' do
path = Path.new(nil, nil, {})
allow(path).to receive(:path) { '/the/path' }
allow(path).to receive(:uses_specific_format?) { true }
allow(path).to receive(:settings) { { format: :json } }

expect(path.path_with_suffix).to eql('/the/path')
expect(path.path_with_suffix).to eql('/the/path(.json)')
end
end
end
Expand Down