Skip to content

Commit fd4addb

Browse files
committed
Merge pull request #31 from marlonandrade/custom-response-headers
Allowing to configure custom headers for Total and Per-Page
2 parents 601c2e4 + 26f434a commit fd4addb

File tree

6 files changed

+110
-6
lines changed

6 files changed

+110
-6
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ class MoviesAPI < Grape::API
100100
end
101101
```
102102

103+
## Headers
104+
103105
Then `curl --include` to see your header-based pagination in action:
104106

105107
```bash
@@ -114,6 +116,27 @@ Per-Page: 10
114116
# ...
115117
```
116118

119+
If you want, you can customize the name of `Total` and `Per-Page` headers.
120+
All you need to do is to set the `total_header` or `per_page_header` on `ApiPagination`.
121+
If nothing is setted it defaults to `Total` and `Per-Page`.
122+
123+
```ruby
124+
ApiPagination.total_header = 'X-Total-Count'
125+
ApiPagination.per_page_header = 'X-Per-Page'
126+
```
127+
128+
```bash
129+
$ curl --include 'https://localhost:3000/movies?page=5'
130+
HTTP/1.1 200 OK
131+
Link: <http://localhost:3000/movies?page=1>; rel="first",
132+
<http://localhost:3000/movies?page=173>; rel="last",
133+
<http://localhost:3000/movies?page=6>; rel="next",
134+
<http://localhost:3000/movies?page=4>; rel="prev"
135+
X-Total-Count: 4321
136+
X-Per-Page: 10
137+
# ...
138+
```
139+
117140
[kaminari]: https://github.com/amatsuda/kaminari
118141
[will_paginate]: https://github.com/mislav/will_paginate
119142

lib/api-pagination.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
module ApiPagination
44
class << self
55
attr_reader :paginator
6+
attr_writer :total_header, :per_page_header
67

78
def paginate(collection, options = {})
89
options[:page] = options[:page].to_i
@@ -51,6 +52,14 @@ def total_from(collection)
5152
when :will_paginate then collection.total_entries.to_s
5253
end
5354
end
55+
56+
def total_header
57+
@total_header ||= 'Total'
58+
end
59+
60+
def per_page_header
61+
@per_page_header ||= 'Per-Page'
62+
end
5463
end
5564
end
5665

lib/grape/pagination.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@ def paginate(collection)
2020
links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
2121
end
2222

23-
header 'Link', links.join(', ') unless links.empty?
24-
header 'Total', ApiPagination.total_from(collection)
25-
header 'Per-Page', options[:per_page]
23+
total_header = ApiPagination.total_header
24+
per_page_header = ApiPagination.per_page_header
25+
26+
header 'Link', links.join(', ') unless links.empty?
27+
header total_header, ApiPagination.total_from(collection)
28+
header per_page_header, options[:per_page].to_s
2629

2730
return collection
2831
end

lib/rails/pagination.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,12 @@ def _paginate_collection(collection, options={})
3939
links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
4040
end
4141

42-
headers['Link'] = links.join(', ') unless links.empty?
43-
headers['Total'] = ApiPagination.total_from(collection)
44-
headers['Per-Page'] = options[:per_page].to_s
42+
total_header = ApiPagination.total_header
43+
per_page_header = ApiPagination.per_page_header
44+
45+
headers['Link'] = links.join(', ') unless links.empty?
46+
headers[total_header] = ApiPagination.total_from(collection)
47+
headers[per_page_header] = options[:per_page].to_s
4548

4649
return collection
4750
end

spec/grape_spec.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,38 @@
6666
end
6767
end
6868
end
69+
70+
context 'with custom response headers' do
71+
before do
72+
ApiPagination.total_header = 'X-Total-Count'
73+
ApiPagination.per_page_header = 'X-Per-Page'
74+
75+
get '/numbers', count: 10
76+
end
77+
78+
after do
79+
ApiPagination.total_header = nil
80+
ApiPagination.per_page_header = nil
81+
end
82+
83+
let(:total) { last_response.header['X-Total-Count'].to_i }
84+
let(:per_page) { last_response.header['X-Per-Page'].to_i }
85+
86+
it 'should give a X-Total-Count header' do
87+
headers_keys = last_response.headers.keys
88+
89+
expect(headers_keys).not_to include('Total')
90+
expect(headers_keys).to include('X-Total-Count')
91+
expect(total).to eq(10)
92+
end
93+
94+
it 'should give a X-Per-Page header' do
95+
headers_keys = last_response.headers.keys
96+
97+
expect(headers_keys).not_to include('Per-Page')
98+
expect(headers_keys).to include('X-Per-Page')
99+
expect(per_page).to eq(10)
100+
end
101+
end
69102
end
70103
end

spec/rails_spec.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,38 @@
6868
expect(response.body).to eq(json)
6969
end
7070
end
71+
72+
context 'with custom response headers' do
73+
before do
74+
ApiPagination.total_header = 'X-Total-Count'
75+
ApiPagination.per_page_header = 'X-Per-Page'
76+
77+
get :index, count: 10
78+
end
79+
80+
after do
81+
ApiPagination.total_header = nil
82+
ApiPagination.per_page_header = nil
83+
end
84+
85+
let(:total) { response.header['X-Total-Count'].to_i }
86+
let(:per_page) { response.header['X-Per-Page'].to_i }
87+
88+
it 'should give a X-Total-Count header' do
89+
headers_keys = response.headers.keys
90+
91+
expect(headers_keys).not_to include('Total')
92+
expect(headers_keys).to include('X-Total-Count')
93+
expect(total).to eq(10)
94+
end
95+
96+
it 'should give a X-Per-Page header' do
97+
headers_keys = response.headers.keys
98+
99+
expect(headers_keys).not_to include('Per-Page')
100+
expect(headers_keys).to include('X-Per-Page')
101+
expect(per_page).to eq(10)
102+
end
103+
end
71104
end
72105
end

0 commit comments

Comments
 (0)