Skip to content

Commit a0b3e6b

Browse files
author
Owen Davies
committed
Add max_per_page value to grape swagger docs
If a max_per_page value is added to grape then it is show in the docs. This avoids confusing if someone tries to pass in a value greater than max_per_page as it will return an error so the user can correct themself. Note this may be a breaking change for some people.
1 parent 3bf4feb commit a0b3e6b

File tree

4 files changed

+58
-6
lines changed

4 files changed

+58
-6
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,15 @@ class MoviesAPI < Grape::API
138138
get :cast do
139139
paginate Movie.find(params[:id]).actors
140140
end
141+
142+
desc "Return one movie's awards, paginated"
143+
# Enforce max_per_page value will add the alowed values
144+
# to the swagger docs, and cause grape to return an error
145+
# if outside that range
146+
paginate per_page: 10, max_per_page: 200, enforce_max_per_page: true
147+
get :awards do
148+
paginate Movie.find(params[:id]).awards
149+
end
141150
end
142151
end
143152
```

lib/grape/pagination.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,16 @@ def paginate(collection)
3939
def self.paginate(options = {})
4040
route_setting :per_page, options[:per_page]
4141
route_setting :max_per_page, options[:max_per_page]
42+
43+
enforce_max_per_page = options[:max_per_page] && options[:enforce_max_per_page]
44+
per_page_values = enforce_max_per_page ? 0..options[:max_per_page] : nil
45+
4246
params do
43-
optional :page, :type => Integer, :default => 1,
44-
:desc => 'Page of results to fetch.'
45-
optional :per_page, :type => Integer,
46-
:desc => 'Number of results to return per page.'
47+
optional :page, :type => Integer, :default => 1,
48+
:desc => 'Page of results to fetch.'
49+
optional :per_page, :type => Integer,
50+
:desc => 'Number of results to return per page.',
51+
:values => per_page_values
4752
end
4853
end
4954
end

spec/grape_spec.rb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,35 @@
5656
it_behaves_like 'an endpoint with a middle page'
5757
end
5858

59-
context 'with a max_per_page setting' do
59+
context 'without a max_per_page setting' do
6060
before { get '/numbers', :count => 100, :per_page => 30 }
6161

62+
it 'should list all numbers within per page in the response body' do
63+
body = '[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]'
64+
65+
expect(last_response.body).to eq(body)
66+
end
67+
end
68+
69+
context 'with a max_per_page setting not enforced' do
70+
before { get '/numbers_with_max_per_page', :count => 100, :per_page => 30 }
71+
6272
it 'should not go above the max_per_page_limit' do
6373
body = '[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]'
6474

6575
expect(last_response.body).to eq(body)
6676
end
6777
end
78+
79+
context 'with a max_per_page setting enforced' do
80+
before { get '/numbers_with_enforced_max_per_page', :count => 100, :per_page => 30 }
81+
82+
it 'should not allow value above the max_per_page_limit' do
83+
body = '{"error":"per_page does not have a valid value"}'
84+
85+
expect(last_response.body).to eq(body)
86+
end
87+
end
6888
end
6989

7090
context 'with custom response headers' do

spec/support/numbers_api.rb

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class NumbersAPI < Grape::API
55
format :json
66

77
desc 'Return some paginated set of numbers'
8-
paginate :per_page => 10, :max_per_page => 25
8+
paginate :per_page => 10
99
params do
1010
requires :count, :type => Integer
1111
optional :with_headers, :default => false, :type => Boolean
@@ -20,4 +20,22 @@ class NumbersAPI < Grape::API
2020

2121
paginate (1..params[:count]).to_a
2222
end
23+
24+
desc 'Return some paginated set of numbers with max_per_page'
25+
paginate :per_page => 10, :max_per_page => 25
26+
params do
27+
requires :count, :type => Integer
28+
end
29+
get :numbers_with_max_per_page do
30+
paginate (1..params[:count]).to_a
31+
end
32+
33+
desc 'Return some paginated set of numbers with max_per_page enforced'
34+
paginate :per_page => 10, :max_per_page => 25, :enforce_max_per_page => true
35+
params do
36+
requires :count, :type => Integer
37+
end
38+
get :numbers_with_enforced_max_per_page do
39+
paginate (1..params[:count]).to_a
40+
end
2341
end

0 commit comments

Comments
 (0)