pagination

package module
v0.0.0-...-57d10ff Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2024 License: MIT Imports: 7 Imported by: 0

README

Go

Pagination

API pagination is a ubiquitous feature and ocasionaly contraversial topic.

This repository provides an opinionated Specification for performing pagination along with a golang library for ease of implementation.

The Specification also adresses the topic of backwards compatibility with other pagination methods. The golang library also provides helpers for this.

Usage

middleware := pagination.NewMiddleware()

r := chi.NewRouter()

r.With(middleware).Get("/items", func(w http.ResponseWriter, r *http.Request) {
    fmt.Printf("request: maxItems=%d page=%q\n", pagination.MaxItems(r), pagination.Page(r))

    pagination.SetNext(r, "test") // dummy example token, replace with your own
    w.Write([]byte("...Data..."))
})

http.ListenAndServe(":8080", r)

Pagination flow

sequenceDiagram
    participant Client
    participant Server

    Note left of Client: Request first page
    Client->>+Server: GET https://example.com/items?maxItems=5
    Server-->>Client: Link: <https://example.com/items?maxItems=5&page=3hj53>#59; rel=#34;next#34;
    Server-->>Client: <body>
    deactivate Server

    Note left of Client: Follow link to next page
    Client->>+Server: GET https://example.com/items?maxItems=5&page=3hj53
    Server-->>Client: Link: <https://example.com/items?maxItems=5>#59; rel=#34;prev#34;
    Server-->>Client: <body>
    deactivate Server

    Note left of Client: No next link,<br>pagination finished

See the Specification for a full explanation.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodeToken

func DecodeToken(token string, container interface{}) error

func EncodeToken

func EncodeToken(container interface{}) (string, error)

func MaxItems

func MaxItems(r *http.Request) int

func Page

func Page(r *http.Request) string

func SetFirst

func SetFirst(r *http.Request, page string)

func SetLast

func SetLast(r *http.Request, page string)

func SetNext

func SetNext(r *http.Request, page string)

func SetPrev

func SetPrev(r *http.Request, page string)

Types

type Middleware

type Middleware func(http.Handler) http.Handler
Example (BackwardsCompatible)
middleware := pagination.NewMiddleware(
	// provide a function to rewrite legacy URLs to the new format
	pagination.WithBackwardsCompatibility(shim),
)

r := chi.NewRouter()
r.With(middleware).Get("/items", func(w http.ResponseWriter, r *http.Request) {
	fmt.Printf("request: maxItems=%d page=%q\n", pagination.MaxItems(r), pagination.Page(r))

	pagination.SetNext(r, "test") // dummy example token, replace with your own
	w.Write([]byte("...Data..."))
})

// Simulate a request to the handler and print the response headers
// real applications should use http.ListenAndServe or similar
simulateRequest(r, "https://example.com/items")
simulateRequest(r, "https://example.com/items?limit=10&cursor=abc")
Output:

request: maxItems=100 page=""
response: [<https://example.com/items?maxItems=100&page=test>; rel="next"]
request: maxItems=10 page="abc"
response: [<https://example.com/items?maxItems=10&page=abc>; rel="alternate" <https://example.com/items?maxItems=10&page=test>; rel="next"]
Example (Simple)
middleware := pagination.NewMiddleware()

r := chi.NewRouter()
r.With(middleware).Get("/items", func(w http.ResponseWriter, r *http.Request) {
	fmt.Printf("request: maxItems=%d page=%q\n", pagination.MaxItems(r), pagination.Page(r))

	pagination.SetNext(r, "test") // dummy example token, replace with your own
	w.Write([]byte("...Data..."))
})

// Simulate a request to the handler and print the response headers
// real applications should use http.ListenAndServe or similar
simulateRequest(r, "https://example.com/items")
simulateRequest(r, "https://example.com/items?maxItems=10&page=abc")
Output:

request: maxItems=100 page=""
response: [<https://example.com/items?maxItems=100&page=test>; rel="next"]
request: maxItems=10 page="abc"
response: [<https://example.com/items?maxItems=10&page=test>; rel="next"]

func NewMiddleware

func NewMiddleware(opts ...MiddlewareOpt) Middleware

type MiddlewareOpt

type MiddlewareOpt func(*middleware)

func WithBackwardsCompatibility

func WithBackwardsCompatibility(shim Rewriter) MiddlewareOpt

func WithMaxItemsDefault

func WithMaxItemsDefault(maxItems int) MiddlewareOpt

func WithMaxItemsLimit

func WithMaxItemsLimit(maxItems int) MiddlewareOpt

type Rewriter

type Rewriter func(url.URL) (url.URL, bool)

Rewriter is a function that can be used to rewrite URLs to support legacy pagination methods.

If the URL is rewritten, the second return value should be true. If the URL is not rewritten, the given URL should be returned and the second return value should be false.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL