Skip to content

Commit d31918e

Browse files
committed
Merge pull request #1001 from hodak/deeply-include-format-option-issue-965
Use proper .format suffix if you have one path, issue 965
2 parents bc7db69 + ca16c5c commit d31918e

File tree

7 files changed

+95
-9
lines changed

7 files changed

+95
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* [#988](https://github.com/intridea/grape/pull/988): Fixed duplicate identical endpoints - [@u2](https://github.com/u2).
1919
* [#936](https://github.com/intridea/grape/pull/936): Fixed default params processing for optional groups - [@dm1try](https://github.com/dm1try).
2020
* [#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).
21+
* [#1001](https://github.com/intridea/grape/pull/1001): Fixed calling endpoint with specified format with format in its path - [@hodak](https://github.com/hodak).
2122

2223
* Your contribution here.
2324

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,7 +1680,7 @@ end
16801680
```
16811681

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

16851685
```ruby
16861686
class SingleFormatAPI < Grape::API
@@ -1693,7 +1693,8 @@ end
16931693
```
16941694

16951695
* `GET /hello` will respond with JSON.
1696-
* `GET /hello.xml`, `GET /hello.json`, `GET /hello.foobar`, or *any* other extension will respond with an HTTP 404 error code.
1696+
* `GET /hello.json` will respond with JSON.
1697+
* `GET /hello.xml`, `GET /hello.foobar`, or *any* other extension will respond with an HTTP 404 error code.
16971698
* `GET /hello?format=xml` will respond with an HTTP 406 error code, because the XML format specified by the request parameter
16981699
is not supported.
16991700
* `GET /hello` with an `Accept: application/xml` header will still respond with JSON, since it could not negotiate a

UPGRADING.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ error!(e)
5656

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

59+
#### Changes to routes when using `format`
60+
61+
Now it's possible to call API with proper suffix when single `format` is defined. I. e.
62+
63+
```ruby
64+
class API < Grape::API
65+
format :json
66+
67+
get :hello do
68+
{ hello: 'world' }
69+
end
70+
end
71+
```
72+
73+
Will respond with JSON to `/hello` **and** `/hello.json`.
74+
75+
Will respond with 404 to `/hello.xml`, `/hello.txt` etc.
76+
77+
See the [#1001](https://github.com/intridea/grape/pull/1001) for more info.
78+
5979
### Upgrading to >= 0.11.0
6080

6181
#### Added Rack 1.6.0 support

lib/grape/path.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def has_path?
3838

3939
def suffix
4040
if uses_specific_format?
41-
''
41+
"(.#{settings[:format]})"
4242
elsif !uses_path_versioning? || (has_namespace? || has_path?)
4343
'(.:format)'
4444
else
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
require 'spec_helper'
2+
3+
module API
4+
module Defaults
5+
extend ActiveSupport::Concern
6+
included do
7+
format :json
8+
end
9+
end
10+
11+
module Admin
12+
module Defaults
13+
extend ActiveSupport::Concern
14+
include API::Defaults
15+
end
16+
17+
class Users < Grape::API
18+
include API::Admin::Defaults
19+
20+
resource :users do
21+
get do
22+
status 200
23+
end
24+
end
25+
end
26+
end
27+
end
28+
29+
class Main < Grape::API
30+
mount API::Admin::Users
31+
end
32+
33+
describe Grape::API do
34+
subject { Main }
35+
36+
def app
37+
subject
38+
end
39+
40+
it 'works for unspecified format' do
41+
get '/users'
42+
expect(last_response.status).to eql 200
43+
expect(last_response.content_type).to eql 'application/json'
44+
end
45+
46+
it 'works for specified format' do
47+
get '/users.json'
48+
expect(last_response.status).to eql 200
49+
expect(last_response.content_type).to eql 'application/json'
50+
end
51+
52+
it "doesn't work for format different than specified" do
53+
get '/users.txt'
54+
expect(last_response.status).to eql 404
55+
end
56+
end

spec/grape/api_spec.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -804,14 +804,16 @@ def subject.enable_root_route!
804804
it 'sets content type for json error' do
805805
subject.format :json
806806
subject.get('/error') { error!('error in json', 500) }
807-
get '/error'
807+
get '/error.json'
808+
expect(last_response.status).to eql 500
808809
expect(last_response.headers['Content-Type']).to eql 'application/json'
809810
end
810811

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

@@ -2642,7 +2644,11 @@ def static
26422644
get '/meaning_of_life'
26432645
expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s)
26442646
end
2645-
it 'does not accept any extensions' do
2647+
it 'accepts specified extension' do
2648+
get '/meaning_of_life.txt'
2649+
expect(last_response.body).to eq({ meaning_of_life: 42 }.to_s)
2650+
end
2651+
it 'does not accept extensions other than specified' do
26462652
get '/meaning_of_life.json'
26472653
expect(last_response.status).to eq(404)
26482654
end

spec/grape/path_spec.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,12 @@ module Grape
182182

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

189-
expect(path.suffix).to eql('')
190+
expect(path.suffix).to eql('(.json)')
190191
end
191192
end
192193

@@ -237,12 +238,13 @@ module Grape
237238
end
238239

239240
context 'when using a specific format' do
240-
it 'does not have a suffix' do
241+
it 'might have a suffix with specified format' do
241242
path = Path.new(nil, nil, {})
242243
allow(path).to receive(:path) { '/the/path' }
243244
allow(path).to receive(:uses_specific_format?) { true }
245+
allow(path).to receive(:settings) { { format: :json } }
244246

245-
expect(path.path_with_suffix).to eql('/the/path')
247+
expect(path.path_with_suffix).to eql('/the/path(.json)')
246248
end
247249
end
248250
end

0 commit comments

Comments
 (0)