https://github.com/gemcook/pagination-go
format pagination response on server side
https://github.com/gemcook/pagination-go
golang pagination
Last synced: 3 months ago
JSON representation
format pagination response on server side
- Host: GitHub
- URL: https://github.com/gemcook/pagination-go
- Owner: gemcook
- License: mit
- Created: 2018-05-02T03:25:55.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2023-12-15T02:52:24.000Z (over 2 years ago)
- Last Synced: 2025-03-29T07:05:23.590Z (about 1 year ago)
- Topics: golang, pagination
- Language: Go
- Homepage:
- Size: 33.2 KB
- Stars: 32
- Watchers: 1
- Forks: 5
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# pagination-go
[](https://circleci.com/gh/gemcook/pagination-go/tree/master) [](https://coveralls.io/github/gemcook/pagination-go?branch=master)
This is a helper library which perfectly matches for server-side implementation of [@gemcook/pagination](https://github.com/gemcook/pagination)
## Installation
```sh
go get -u github.com/gemcook/pagination-go
```
If you use `dep`
```sh
dep ensure -add github.com/gemcook/pagination-go
```
## Usage
### fetcher interface
Your fetching object must implement fetcher interface.
```go
type PageFetcher interface {
Count(cond interface{}) (int, error)
FetchPage(cond interface{}, input *PageFetchInput, result *PageFetchResult) error
}
type PageFetchInput struct {
Limit int
Offset int
Orders []*Order
}
```
### parse Function
Package `pagination` provides `ParseQuery` and `ParseMap` functions that parses Query Parameters from request URL.
Those query parameters below will be parsed.
| query parameter | Mapped field | required | expected value | default value |
| --------------- | ------------ | -------- | --------------------- | ------------- |
| `limit` | `Limit` | no | positive integer | `10` |
| `page` | `Page` | no | positive integer (1~) | `1` |
| `pagination` | `Enabled` | no | boolean | `true` |
#### Query String from URL
```go
// RequestURI: https://example.com/fruits?limit=10&page=1&price_range=100,300&sort=+price&pagination=true
p := pagination.ParseQuery(r.URL.RequestURI())
fmt.Println("limit =", p.Limit)
fmt.Println("page =", p.Page)
fmt.Println("pagination =", p.Enabled)
```
#### Query Parameters from AWS API Gateway - Lambda
```go
import "github.com/aws/aws-lambda-go/events"
func Handler(event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
// event.QueryStringParameters
// map[string]string{"limit": "10", "page": "1", "pagination": "false"}
p := pagination.ParseMap(event.QueryStringParameters)
fmt.Println("limit =", p.Limit)
fmt.Println("page =", p.Page)
fmt.Println("pagination =", p.Enabled)
}
```
### fetching condition [OPTIONAL]
Tell pagination the condition to filter resources.
Then use `cond interface{}` in `Count` and `FetchPage` function.
Use type assertion for `cond` to restore your fetching condition object.
### Orders [OPTIONAL]
Optionally, pagination takes orders.
Use `pagination.ParseQuery` or `pagination.ParseMap` to parse sort parameter in query string.
Then, just pass `Query.Sort` to `Setting.Orders`.
Those query parameters below will be parsed.
| query parameter | Mapped field | required | expected value | default value |
| --------------- | ------------ | -------- | ---------------------------------------------------------------------------- | ------------- |
| `sort` | `Sort` | no | `+column_name` for ascending sort. `-column_name` for descending sort. | `nil` |
## Example
```go
import (
"http/net"
"encoding/json"
"strconv"
"github.com/gemcook/pagination-go"
)
type fruitFetcher struct{}
type FruitCondition struct{
PriceLowerLimit int
PriceHigherLimit int
}
func ParseFruitCondition(uri string) *FruitCondition {
// parse uri and initialize struct
}
func handler(w http.ResponseWriter, r *http.Request) {
// RequestURI: https://example.com/fruits?limit=10&page=1&price_range=100,300&sort=+price
p := pagination.ParseQuery(r.URL.RequestURI())
cond := parseFruitCondition(r.URL.RequestURI())
fetcher := newFruitFetcher()
totalCount, totalPages, res, err := pagination.Fetch(fetcher, &pagination.Setting{
Limit: p.Limit,
Page: p.Page,
Cond: cond,
Orders: p.Sort,
})
if err != nil {
w.Header().Set("Content-Type", "text/html; charset=utf8")
w.WriteHeader(400)
fmt.Fprintf(w, "something wrong: %v", err)
return
}
w.Header().Set("X-Total-Count", strconv.Itoa(totalCount))
w.Header().Set("X-Total-Pages", strconv.Itoa(totalPages))
w.Header().Set("Access-Control-Expose-Headers", "X-Total-Count,X-Total-Pages")
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(200)
resJSON, _ := json.Marshal(res)
w.Write(resJSON)
}
```
For full source code, see [example/server.go](./example/server.go).
Run example.
```sh
cd example
go run server.go
```
Then open `http://localhost:8080/fruits?limit=2&page=1&price_range=100,300&sort=+price`