pagination

package
v0.24.0 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2020 License: Apache-2.0 Imports: 7 Imported by: 0

README

Pagination

The pagination package works with a combination of two types:

the pagination.Request and pagination.Response types.

The Request allows a client to pass in parameters to the server:

  • page: which page the client wants to see
  • per_page: how many items the client wants on each page.

From this request, a Response can be constructed, once you know how many total items you are going to respond with. When making a new pagination response, offset and last page values are calculated automatically.

Examples

Create a paginator
func ExamplePagination() {
	preq := pagination.Request{
		PerPage: 10,
		Page:    1,
	}
	presp := pagination.MakeResponse(preq, 100)
	fmt.Printf("%+v\n", presp)
	// Output: {PerPage:10 Page:1 Offset:0 Total:100 LastPage:10}
}
Create a paginator, with an offset
func ExampleOffsetPagination() {
	preq := pagination.Request{
		PerPage: 10,
		Page:    2,
	}
	presp := pagination.MakeResponse(preq, 100)
	fmt.Printf("%+v\n", presp)
	// Output: {PerPage:10 Page:2 Offset:10 Total:100 LastPage:10}
}
Create a paginator and use it in an HTTP response
func ExamplePaginationResponse() {
	preq := pagination.Request{
		PerPage: 10,
		Page:    2,
	}
	presp := pagination.MakeResponse(preq, 100)

	resp := rest.Response{
		Code:    http.StatusOK,
		Message: "some helpful message",
		Data: &rest.Data{
			Type:    "some_data",
			Content: map[string]interface{}{"hello": "world"},
		},
		Pagination: &presp,
	}
	raw, _ := json.MarshalIndent(resp, "", "\t")
	fmt.Println(string(raw))
	// Output:
	// {
	// 	"code": 200,
	// 	"message": "some helpful message",
	// 	"data": {
	// 		"some_data": {
	// 			"hello": "world"
	// 		}
	// 	},
	// 	"pagination": {
	// 		"per_page": 10,
	// 		"page": 2,
	// 		"offset": 10,
	// 		"total": 100,
	// 		"last_page": 10
	// 	}
	// }
}

Documentation

Overview

Package pagination defines a paginator able to return formatted responses enabling the API consumer to retrieve data in defined chunks

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrCalculateOffset is used when the pagination offset could not be calculated.
	ErrCalculateOffset = errors.New("cannot calculate offset: insufficient data")

	// ErrMetadataInvalid happens when a metadata key is invalid or missing
	ErrMetadataInvalid = func(key string, err error) error {
		return status.Error(codes.InvalidArgument, fmt.Sprintf("invalid or missing [%s]: %v", key, err))
	}
)

Functions

func ContextWithRequest

func ContextWithRequest(parent context.Context, req Request) context.Context

ContextWithRequest takes a context and a pagination request and returns a new context with the pagination request embedded.

Types

type Request

type Request struct {
	PerPage uint64
	Page    uint64
}

Request derives the requested pagination data given by the client.

func RequestFromContext

func RequestFromContext(ctx context.Context) Request

RequestFromContext extracts the pagination request from the supplied context.

func (Request) Metadata added in v0.17.0

func (r Request) Metadata() metadata.MD

Metadata returns gRPC metadata for a pagination request.

func (Request) Offset

func (r Request) Offset() uint64

Offset calculates the offset from the provided pagination request.

type Response

type Response struct {
	PerPage     uint64  `json:"per_page"`     // The number of items per page.
	Offset      uint64  `json:"offset"`       // The current offset to pass to the query.
	Total       uint64  `json:"total"`        // The total number of items
	LastPage    uint64  `json:"last_page"`    // The number of the last possible page.
	CurrentPage uint64  `json:"current_page"` // The current page number.
	NextPage    *uint64 `json:"next_page"`    // The number of the next page (if possible).
	PrevPage    *uint64 `json:"prev_page"`    // The number of the previous page (if possible).
}

Response manages pagination of a data set.

func MakeResponse

func MakeResponse(request Request, total uint64) Response

MakeResponse returns a new Response with the provided parameters set.

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/LUSHDigital/core/pagination"
)

func main() {
	preq := pagination.Request{
		PerPage: 10,
		Page:    1,
	}
	presp := pagination.MakeResponse(preq, 100)
	raw, _ := json.Marshal(presp)
	fmt.Println(string(raw))
}
Output:

{"per_page":10,"offset":0,"total":100,"last_page":10,"current_page":1,"next_page":2,"prev_page":null}
Example (WithOffset)
package main

import (
	"encoding/json"
	"fmt"

	"github.com/LUSHDigital/core/pagination"
)

func main() {
	preq := pagination.Request{
		PerPage: 10,
		Page:    2,
	}
	presp := pagination.MakeResponse(preq, 100)
	raw, _ := json.Marshal(presp)
	fmt.Println(string(raw))
}
Output:

{"per_page":10,"offset":10,"total":100,"last_page":10,"current_page":2,"next_page":3,"prev_page":1}
Example (WithinResponse)
package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/LUSHDigital/core/pagination"
	"github.com/LUSHDigital/core/rest"
)

func main() {
	preq := pagination.Request{
		PerPage: 10,
		Page:    2,
	}
	presp := pagination.MakeResponse(preq, 100)

	resp := rest.Response{
		Code:    http.StatusOK,
		Message: "some helpful message",
		Data: &rest.Data{
			Type:    "some_data",
			Content: map[string]interface{}{"hello": "world"},
		},
		Pagination: &presp,
	}
	raw, _ := json.MarshalIndent(resp, "", "\t")
	fmt.Println(string(raw))
}
Output:

{
	"code": 200,
	"message": "some helpful message",
	"data": {
		"some_data": {
			"hello": "world"
		}
	},
	"pagination": {
		"per_page": 10,
		"offset": 10,
		"total": 100,
		"last_page": 10,
		"current_page": 2,
		"next_page": 3,
		"prev_page": 1
	}
}

func (Response) Metadata added in v0.17.0

func (r Response) Metadata() metadata.MD

Metadata returns gRPC metadata for a pagination response.

Jump to

Keyboard shortcuts

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