mockingpug
Concepts

Pagination

page / offset / cursor strategies, query param names, and response shape

GET list endpoints (/api/user) are paginated according to mock.config.js's pagination block. Every transport (react, next) shares the same implementation, so behavior is identical regardless of how you're serving the data.

Strategies

Set via pagination.strategy:

  • 'page' (default): ?page=2&limit=20. Response meta: { strategy: 'page', total, page, limit, pageCount }.
  • 'offset': ?offset=40&limit=20. Response meta: { strategy: 'offset', total, offset, limit }.
  • 'cursor': ?cursor=<opaque>&limit=20. Response meta: { strategy: 'cursor', total, limit, nextCursor }. nextCursor is null once there's nothing left.
  • false: pagination disabled entirely; GET returns every record.

Query parameter names

Customizable per-project via pagination.params, the defaults:

params: { page: 'page', limit: 'limit', offset: 'offset', cursor: 'cursor', groupBy: 'groupBy', limitPerGroup: 'limitPerGroup' }

Rename limit to perPage, for instance, if that's your existing API's convention:

pagination: { params: { limit: 'perPage' } }

Per-group limit for batch requests

A batch request like ?group_id=1,2,3&limit=20 (the comma-separated OR filter from Filtering, not a dedicated "batch" feature) applies limit once to the flattened result across all three groups — 20 records total, however they happen to split across group_ids 1, 2, and 3, not 20 per group. If your real API instead guarantees N records for each id in a batch fetch (a common shape for something like getProductsByGroupIds), add groupBy (naming the field to group by) and limitPerGroup alongside your filter:

GET /api/product?group_id=1,2,3&groupBy=group_id&limitPerGroup=5

This returns up to 5 products for each of groups 1, 2, and 3 (up to 15 total), applying the cap after grouping instead of once to the whole list. It replaces the normal page/offset/cursor slicing for that request — filtering, search, and sort still run first, same as always — and the response meta switches shape to { strategy: 'group', groupBy, limitPerGroup, totalGroups, total } (envelope: false sets X-Limit-Per-Group, X-Total-Groups, and X-Group-By headers instead of X-Limit/X-Page/etc). Only activates when both groupBy and limitPerGroup are present in the query string — groupBy alone (or limitPerGroup alone) is ignored and normal pagination applies. Not available when pagination.strategy is false, same as the rest of pagination.

Bounds and fallbacks

  • An invalid or non-positive limit in the query string falls back to pagination.defaultLimit. It never produces a 500 or an empty result because of a malformed query param.
  • limit is always clamped to pagination.maxLimit, even if the query string asks for more.

Response envelope

pagination.envelope controls the response body shape:

  • true (default): { data: [...], meta: {...} }.
  • false: a bare array as the body, with pagination info moved to response headers instead: X-Total-Count, X-Limit, and whichever of X-Page / X-Offset / X-Next-Cursor applies to the active strategy.

Pick false if your app's HTTP client (or an existing real API you're mocking the shape of) expects a raw array rather than an envelope object.

On this page