
This is a helper library which perfectly matches for server-side implementation of @gemcook/pagination
Installation
go get -u github.com/gemcook/pagination-go
If you use dep
dep ensure -add github.com/gemcook/pagination-go
Usage
fetcher interface
Your fetching object must implement fetcher interface.
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
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
import "github.com/aws/aws-lambda-go/events"
func Handler(event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
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
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 {
}
func handler(w http.ResponseWriter, r *http.Request) {
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.
Run example.
cd example
go run server.go
Then open http://localhost:8080/fruits?limit=2&page=1&price_range=100,300&sort=+price