Pagination
ss-keel-core provides built-in helpers for offset-based pagination. ParsePagination reads query parameters from the request and Page[T] is the standard paginated response envelope.
ParsePagination
Section titled “ParsePagination”func (c *Ctx) ParsePagination() PageQueryReads ?page and ?limit from the query string and returns a PageQuery.
| Parameter | Default | Max |
|---|---|---|
page | 1 | — |
limit | 20 | 100 |
func (c *UserController) list(ctx *core.Ctx) error { q := ctx.ParsePagination() // q.Page = 1 (or ?page=N) // q.Limit = 20 (or ?limit=N, max 100)
users, total, err := c.service.List(ctx.Context(), q) if err != nil { return err }
return ctx.OK(core.NewPage(users, total, q.Page, q.Limit))}PageQuery
Section titled “PageQuery”type PageQuery struct { Page int Limit int}Pass PageQuery to your repository or service to perform the actual query:
// In your repositoryfunc (r *UserRepo) FindAll(ctx context.Context, q core.PageQuery) (core.Page[User], error) { offset := (q.Page - 1) * q.Limit
rows, err := r.db.QueryContext(ctx, "SELECT * FROM users LIMIT $1 OFFSET $2", q.Limit, offset, ) // ... total := countUsers(ctx) return core.NewPage(users, total, q.Page, q.Limit), nil}Page[T]
Section titled “Page[T]”type Page[T any] struct { Data []T `json:"data"` Total int `json:"total"` Page int `json:"page"` Limit int `json:"limit"` TotalPages int `json:"total_pages"`}NewPage
Section titled “NewPage”func NewPage[T any](data []T, total, page, limit int) Page[T]TotalPages is calculated automatically: ceil(total / limit).
page := core.NewPage(users, 142, 2, 20)// {// "data": [...],// "total": 142,// "page": 2,// "limit": 20,// "total_pages": 8// }JSON Response Example
Section titled “JSON Response Example”GET /users?page=2&limit=10{ "data": [ { "id": "1", "name": "Alice" }, { "id": "2", "name": "Bob" } ], "total": 42, "page": 2, "limit": 10, "total_pages": 5}Repository Interface
Section titled “Repository Interface”The Repository[T, ID] interface uses PageQuery and Page[T] by convention:
type Repository[T any, ID any] interface { FindAll(ctx context.Context, q PageQuery) (Page[T], error) // ...}See Interfaces — Repository for the full interface.