Skip to content

Commit b966af2

Browse files
committed
Populate the Total header
Signed-off-by: David Celis <[email protected]>
1 parent a05aa9a commit b966af2

File tree

11 files changed

+45
-5
lines changed

11 files changed

+45
-5
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# api-pagination [![Build Status](https://travis-ci.org/davidcelis/api-pagination.png)](https://travis-ci.org/davidcelis/api-pagination)
22

3-
Put pagination info in a Link header, not the response body.
3+
Paginate in your headers, not in your response body.
44

55
## Installation
66

@@ -72,7 +72,7 @@ class MoviesAPI < Grape::API
7272
end
7373
```
7474

75-
Then `curl --include` to see your Link header pagination in action:
75+
Then `curl --include` to see your header-based pagination in action:
7676

7777
```bash
7878
$ curl --include 'https://localhost:3000/movies?page=5'
@@ -81,6 +81,7 @@ Link: <http://localhost:3000/movies?page=1>; rel="first">,
8181
<http://localhost:3000/movies?page=173>; rel="last">,
8282
<http://localhost:3000/movies?page=6>; rel="next">,
8383
<http://localhost:3000/movies?page=4>; rel="prev">
84+
Total: 4321
8485
# ...
8586
```
8687

lib/api-pagination.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ def pages_from(collection)
3030
end
3131
end
3232
end
33+
34+
def total_from(collection)
35+
case ApiPagination.paginator
36+
when :kaminari then collection.total_count
37+
when :will_paginate then collection.total_entries
38+
end
39+
end
3340
end
3441
end
3542

lib/grape/pagination.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def paginate(collection)
1515
end
1616

1717
header 'Link', links.join(', ') unless links.empty?
18+
header 'Total', ApiPagination.total_from(collection)
1819
end
1920

2021
ApiPagination.paginate(collection, params, &block)

lib/rails/pagination.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ def paginate(collection)
1515
links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
1616
end
1717

18-
headers['Link'] = links.join(', ') unless links.empty?
18+
headers['Link'] = links.join(', ') unless links.empty?
19+
headers['Total'] = ApiPagination.total_from(collection)
1920
end
2021

2122
ApiPagination.paginate(collection, params, &block)

spec/grape_spec.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@
77
describe NumbersAPI do
88
describe 'GET #index' do
99
let(:links) { last_response.headers['Link'].split(', ') }
10+
let(:total) { last_response.headers['Total'].to_i }
1011

1112
context 'without enough items to give more than one page' do
13+
before { get :numbers, :count => 20 }
14+
1215
it 'should not paginate' do
13-
get :numbers, :count => 20
1416
expect(last_response.headers.keys).not_to include('Link')
1517
end
18+
19+
it 'should give a Total header' do
20+
expect(total).to eq(20)
21+
end
1622
end
1723

1824
context 'with existing Link headers' do

spec/rails_spec.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@
66

77
describe NumbersController, :type => :controller do
88
before { request.host = 'example.org' }
9+
910
describe 'GET #index' do
1011
let(:links) { response.headers['Link'].split(', ') }
12+
let(:total) { response.headers['Total'].to_i }
1113

1214
context 'without enough items to give more than one page' do
15+
before { get :index, :count => 20 }
1316
it 'should not paginate' do
14-
get :index, :count => 20
1517
expect(response.headers.keys).not_to include('Link')
1618
end
19+
20+
it 'should give a Total header' do
21+
expect(total).to eq(20)
22+
end
1723
end
1824

1925
context 'with existing Link headers' do

spec/spec_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def per(per)
2424
def paginate(options = {})
2525
page(options[:page]).per(options[:per_page])
2626
end
27+
28+
alias :total_entries :total_count
2729
end
2830

2931
if ENV['PAGINATOR']

spec/support/shared_examples/existing_headers.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,8 @@
77
expect(links).to include('<http://example.org/numbers?count=30&page=2&with_headers=true>; rel="next"')
88
expect(links).to include('<http://example.org/numbers?count=30&page=2&with_headers=true>; rel="last"')
99
end
10+
11+
it 'should give a Total header' do
12+
expect(total).to eq(30)
13+
end
1014
end

spec/support/shared_examples/first_page.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@
1414
it 'should give a link with rel "next"' do
1515
expect(links).to include('<http://example.org/numbers?count=100&page=2>; rel="next"')
1616
end
17+
18+
it 'should give a Total header' do
19+
expect(total).to eq(100)
20+
end
1721
end

spec/support/shared_examples/last_page.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@
1414
it 'should give a link with rel "prev"' do
1515
expect(links).to include('<http://example.org/numbers?count=100&page=3>; rel="prev"')
1616
end
17+
18+
it 'should give a Total header' do
19+
expect(total).to eq(100)
20+
end
1721
end

0 commit comments

Comments
 (0)