Documentation
¶
Overview ¶
Package pagination allows you to break up large sets of information (i.e., HTTP responses) into smaller, more manageable ones.
Pagination adds complexity to both the service and its clients. The decision to paginate a resource should consider the following:
- expected response size
- e.g. what is the average response size? what are the outliers? how fast are the responses growing?
- complexity of retrieving the resources
- e.g. what is the performance impact of retrieving and processing X resources?
- how fast is the data changing?
- is simple (slow) or complex (fast) pagination most appropriate?
- needs of the client(s)
- e.g. does the client really want/need X records upfront when it is only capable of displaying X/10?
- e.g. limited or unreliable connectivity (i.e. mobile) - what volume of data can the client handle?
A base Pagination struct is supplied along with a JSON implimentation, examples of both below.
Usage:
currentPage := 10 // from user input userLimit := 100 // from user input maxLimit := 250 pag, err := pagination.New(currentPage, userLimit, maxLimit) if err != nil { panic(err) } count := getSomeData() pag.SetItemsTotal(count)
Alt Usage:
r := &http.Request{} // replace with your request object currentPage := 10 // from user input userLimit := 100 // from user input maxLimit := 250 pag, err := pagination.NewJSON(currentPage, userLimit, maxLimit, r) if err != nil { panic(err) } count := getSomeData() pag.SetItemsTotal(count) json := json.Marshal(pag) // return this along with your data to the end user
Implementation Of Simple Pagination In A RESTful JSON API ¶
A resource is considered paginated if a `pagination` attribute is present in the JSON response.
```json
{ "data": { }, "pagination": { } }
```
The `pagination` attribute contains metadata about how the resource is paginated, including a list of URLs for the client(s) to navigate between paged resources. The general idea is to limit the amount of work a client has to do to implement a paginated API. e.g. avoid clients having to build URLs
e.g. https://api-example.com/resource?page=3
{ "data": { }, "pagination": { "page_number": 3, "pages_total": 46, "items_per_page": 15, "items_per_page_limit": 25, "items_total": 689, "first_href": "https://api-example.com/resource?page=1", "last_href": "https://api-example.com/resource?page=45", "next_href": "https://api-example.com/resource?page=4", "previous_href": "https://api-example.com/resource?page=2" } }
Pagination Attributes ¶
- Pages (integers)
- `page_number` the index of the current page
- `pages_total` the total number of pages (i.e. round up the number of items / current page size )
- Items (integers)
- `items_per_page` the current number of items per page
- `items_per_page_limit` the maximum amount of items that can be returned per page
- `items_total` the total number of items
- URLs (strings)
- `first_href` full URL of the first page of resources
- `last_href` full URL of the last page of resources
- `next_href` full URL of the next page of resources. `null` if this is the last page
- `previous_href` full URL of the previous page of resources. `null` if this is the first page
The `page` URL Parameter ¶
The `page` URL parameter is an integer that represents the page indices of a given resource. e.g. `https://api.com/resource?page=12`,
The following can be considered synonymous:
1. `https://api.com/resource` 2. `https://api.com/resource?page=` 3. `https://api.com/resource?page=1`
However, all URLs in the `pagination` attribute should contain the fullest representation (3).
The `limit` URL Parameter ¶
The `limit` URL parameter is an integer that specifies the number of items that should be returned in a page. This should be reflected in the first, last, next, and previous URLs.
e.g. https://api-example.com/resource?page=3&limit=10
{ "data": { }, "pagination": { "page_number": 3, "pages_total": 68, "items_per_page": 10, "items_per_page_limit": 15, "items_total": 675, "first_href": "https://api-example.com/resource?page=1&limit=10", "last_href": "https://api-example.com/resource?page=68&limit=10", "next_href": "https://api-example.com/resource?page=4&limit=10", "previous_href": "https://api-example.com/resource?page=2&limit=10" } }
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type InvalidItemsPerPageError ¶
type InvalidItemsPerPageError int
InvalidItemsPerPageError is the error generated when the requested items per page is invalid
func (InvalidItemsPerPageError) Error ¶
func (e InvalidItemsPerPageError) Error() string
type InvalidPageNumberError ¶
type InvalidPageNumberError int
InvalidPageNumberError is the error generated when the requested page number is invalid
func (InvalidPageNumberError) Error ¶
func (e InvalidPageNumberError) Error() string
type JSON ¶
type JSON struct { Paginator // contains filtered or unexported fields }
JSON extends a basic Paginator but adds the request object
func NewJSON ¶
func NewJSON(pageNumber int, itemsPerPage int, itemsPerPageLimit int, r *http.Request) (j *JSON, err error)
NewJSON creates a new JSON paginator, which extends a basic Paginator but adds the request object
func (JSON) MarshalJSON ¶
MarshalJSON is called when ever the Pagination object is json encoded, we use this chance to set the correct href values (as they depend on other data being set, like number of results)
type JSONFields ¶
type JSONFields struct { PageNumber int `json:"page_number"` PagesTotal *int `json:"pages_total"` ItemsPerPage int `json:"items_per_page"` ItemsPerPageLimit int `json:"items_per_page_limit"` ItemsTotal *int `json:"items_total"` FirstHref string `json:"first_href"` LastHref *string `json:"last_href"` NextHref *string `json:"next_href"` PrevHref *string `json:"prev_href"` }
JSONFields is a seperate to JSON that defines the JSON formatting
type Paginator ¶
type Paginator struct { PageNumber int PagesTotal *int ItemsPerPage int ItemsPerPageLimit int ItemsTotal *int }
Paginator contains all of the basic pagination fields
func (*Paginator) Init ¶
Init configs the Paginator struct, it is used so that we can have child structs inherit Pagination - see JSON for an example
func (*Paginator) Offset ¶
Offset returns the current offset (i.e. for database queries) based on the current page and number of itmes
func (*Paginator) SetItemsTotal ¶
SetItemsTotal will set the ItemsTotal value as well as the dynamic PagesTotal based on ItemsPerPage
type TooManyItemsPerPageError ¶
type TooManyItemsPerPageError struct {
PerPage, MaxPerPage int
}
TooManyItemsPerPageError is the error generated when the requested items per page is greater than the max
func (*TooManyItemsPerPageError) Error ¶
func (e *TooManyItemsPerPageError) Error() string