Skip to content

Commit bb6ee72

Browse files
author
LeFnord
committed
issue #533: allows to overwrite defaults status codes
- adds changelog entry
1 parent 1b7fe2e commit bb6ee72

File tree

7 files changed

+123
-16
lines changed

7 files changed

+123
-16
lines changed

.rubocop_todo.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Metrics/BlockLength:
1818
# Offense count: 3
1919
# Configuration parameters: CountComments.
2020
Metrics/ClassLength:
21-
Max: 240
21+
Max: 247
2222

2323
# Offense count: 10
2424
Metrics/CyclomaticComplexity:

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#### Features
44

5+
* [#534](https://github.com/ruby-grape/grape-swagger/pull/534): Allows to overwrite defaults status codes - [@LeFnord](https://github.com/LeFnord).
56
* Your contribution here.
67

78
#### Fixes

README.md

+35-7
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ add_swagger_documentation \
404404
* [Hiding parameters](#hiding-parameters)
405405
* [Setting a Swagger default value](#default-value)
406406
* [Response documentation](#response)
407+
* [Changing default status codes](#change-status)
407408
* [Extensions](#extensions)
408409

409410

@@ -752,7 +753,7 @@ You can also document the HTTP status codes with a description and a specified m
752753
In the following cases, the schema ref would be taken from route.
753754
754755
```ruby
755-
desc 'thing', failures: [ { code: 400, message: "Invalid parameter entry" } ]
756+
desc 'thing', failures: [ { code: 400, message: 'Invalid parameter entry' } ]
756757
get '/thing' do
757758
...
758759
end
@@ -761,7 +762,7 @@ end
761762
```ruby
762763
desc 'thing' do
763764
params Entities::Something.documentation
764-
failures [ { code: 400, message: "Invalid parameter entry" } ]
765+
failures [ { code: 400, message: 'Invalid parameter entry' } ]
765766
end
766767
get '/thing' do
767768
...
@@ -770,8 +771,8 @@ end
770771
771772
```ruby
772773
get '/thing', failures: [
773-
{ code: 200, message: 'Ok' },
774-
{ code: 400, message: "Invalid parameter entry" }
774+
{ code: 400, message: 'Invalid parameter entry' },
775+
{ code: 404, message: 'Not authorized' },
775776
] do
776777
...
777778
end
@@ -780,13 +781,13 @@ end
780781
By adding a `model` key, e.g. this would be taken.
781782
```ruby
782783
get '/thing', failures: [
783-
{ code: 200, message: 'Ok' },
784-
{ code: 422, message: "Invalid parameter entry", model: Entities::ApiError }
784+
{ code: 400, message: 'General error' },
785+
{ code: 422, message: 'Invalid parameter entry', model: Entities::ApiError }
785786
] do
786787
...
787788
end
788789
```
789-
If no status code is defined [defaults](/lib/grape-swagger/endpoint.rb#L121) would be taken.
790+
If no status code is defined [defaults](/lib/grape-swagger/endpoint.rb#L210) would be taken.
790791
791792
The result is then something like following:
792793
@@ -807,6 +808,33 @@ The result is then something like following:
807808
},
808809
```
809810
811+
<a name="change-status" />
812+
#### Changing default status codes
813+
814+
The default status codes, one could be found (-> [status codes](lib/grape-swagger/doc_methods/status_codes.rb)) can be changed to your specific needs, to achive it, you have to change it for grape itself and for the documentation.
815+
816+
```ruby
817+
desc 'Get a list of stuff',
818+
success: { code: 202, model: Entities::UseResponse, message: 'a changed status code' }
819+
get do
820+
status 202
821+
# your code comes here
822+
end
823+
824+
```
825+
826+
```json
827+
"responses": {
828+
"202": {
829+
"description": "ok",
830+
"schema": {
831+
"$ref": "#/definitions/UseResponse"
832+
}
833+
}
834+
},
835+
```
836+
837+
810838
<a name="extensions" />
811839
#### Extensions
812840

lib/grape-swagger/doc_methods/status_codes.rb

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ def get
88
post: { code: 201, message: 'created {item}' },
99
put: { code: 200, message: 'updated {item}' },
1010
patch: { code: 200, message: 'patched {item}' },
11+
# 200 for delete would only be used, if a success entity is given,
12+
# else it would be set to 204
1113
delete: { code: 200, message: 'deleted {item}' },
1214
head: { code: 200, message: 'head {item}' },
1315
options: { code: 200, message: 'option {item}' }

lib/grape-swagger/endpoint.rb

+13-5
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@ def params_object(route)
178178

179179
def response_object(route, markdown)
180180
codes = (route.http_codes || route.options[:failure] || [])
181-
codes = apply_defaults(route, codes) if route.options[:ignore_defaults].nil?
182181

182+
codes = apply_success_codes(route) + codes
183183
codes.map! { |x| x.is_a?(Array) ? { code: x[0], message: x[1], model: x[2] } : x }
184184

185185
codes.each_with_object({}) do |value, memo|
@@ -207,11 +207,19 @@ def response_object(route, markdown)
207207
end
208208
end
209209

210-
def apply_defaults(route, codes)
210+
def apply_success_codes(route)
211211
default_code = GrapeSwagger::DocMethods::StatusCodes.get[route.request_method.downcase.to_sym]
212-
default_code[:model] = @entity if @entity
213-
default_code[:message] = route.description || default_code[:message].sub('{item}', @item)
214-
[default_code] + codes
212+
if @entity.is_a?(Hash)
213+
default_code[:code] = @entity[:code] if @entity[:code].present?
214+
default_code[:model] = @entity[:model] if @entity[:model].present?
215+
default_code[:message] = @entity[:message] || route.description || default_code[:message].sub('{item}', @item)
216+
else
217+
default_code = GrapeSwagger::DocMethods::StatusCodes.get[route.request_method.downcase.to_sym]
218+
default_code[:model] = @entity if @entity
219+
default_code[:message] = route.description || default_code[:message].sub('{item}', @item)
220+
end
221+
222+
[default_code]
215223
end
216224

217225
def tag_object(route)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
require 'spec_helper'
2+
3+
describe '#533 specify status codes' do
4+
include_context "#{MODEL_PARSER} swagger example"
5+
6+
let(:app) do
7+
Class.new(Grape::API) do
8+
namespace :issue_533 do
9+
desc 'Get a list of stuff',
10+
success: { code: 202, model: Entities::UseResponse, message: 'a changed status code' }
11+
get do
12+
status 202
13+
{ foo: 'that is the response' }
14+
end
15+
16+
desc 'Post some stuff',
17+
success: { code: 202, model: Entities::UseResponse, message: 'a changed status code' }
18+
post do
19+
status 202
20+
{ foo: 'that is the response' }
21+
end
22+
23+
desc 'Post some stuff',
24+
success: { code: 204, message: 'a changed status code' }
25+
patch do
26+
status 204
27+
end
28+
29+
desc 'Delete some stuff',
30+
success: { code: 203 }
31+
delete do
32+
status 203
33+
end
34+
end
35+
36+
add_swagger_documentation format: :json
37+
end
38+
end
39+
40+
subject do
41+
get '/swagger_doc'
42+
JSON.parse(last_response.body)['paths']['/issue_533']
43+
end
44+
45+
let(:get_response) { subject['get']['responses'] }
46+
specify do
47+
expect(get_response.keys.first).to eql '202'
48+
expect(get_response['202']).to include 'schema'
49+
end
50+
51+
let(:post_response) { subject['post']['responses'] }
52+
specify do
53+
expect(post_response.keys.first).to eql '202'
54+
expect(post_response['202']).to include 'schema'
55+
end
56+
57+
let(:patch_response) { subject['patch']['responses'] }
58+
specify do
59+
expect(patch_response.keys.first).to eql '204'
60+
expect(patch_response['204']).not_to include 'schema'
61+
end
62+
63+
let(:delete_response) { subject['delete']['responses'] }
64+
specify do
65+
expect(delete_response.keys.first).to eql '203'
66+
expect(delete_response['203']).not_to include 'schema'
67+
end
68+
end

spec/swagger_v2/api_swagger_v2_ignore_defaults_spec.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ def app
88
format :json
99

1010
desc 'This creates Thing after a delay',
11-
success: Entities::Something
11+
success: { code: 202, message: 'OK', model: Entities::Something }
1212
params do
1313
requires :text, type: String, documentation: { type: 'string', desc: 'Content of something.' }
1414
requires :links, type: Array, documentation: { type: 'link', is_array: true }
1515
end
16-
post '/delay_thing', http_codes: [{ code: 202, message: 'OK' }], ignore_defaults: true do
16+
post '/delay_thing' do
1717
status 202
1818
end
1919

@@ -40,7 +40,7 @@ def app
4040
let(:json) { JSON.parse(last_response.body) }
4141

4242
it 'only returns one response if ignore_defaults is specified' do
43-
expect(json['paths']['/delay_thing']['post']['responses']).to eq('202' => { 'description' => 'OK' })
43+
expect(json['paths']['/delay_thing']['post']['responses']).to eq('202' => { 'description' => 'OK', 'schema' => { '$ref' => '#/definitions/Something' } })
4444
expect(json['paths']['/delay_thing']['post']['responses'].keys).not_to include '201'
4545
end
4646
end

0 commit comments

Comments
 (0)