Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Json Api Paginate Laravel Package

spatie/laravel-json-api-paginate

A Laravel package that adds a jsonPaginate method to the Eloquent query builder, so pagination reads page[number] and page[size] request parameters and returns the pagination links required by the JSON:API spec.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is a thin, single-purpose extension: it registers a jsonPaginate() macro on Eloquent's query builder (and relation builders) that reads page[number] / page[size] (and optionally page[cursor]) instead of Laravel's native page, and emits JSON:API-shaped pagination links. Architecturally it is a convention adapter, not a JSON:API implementation. It does not touch serialization, content negotiation, application/vnd.api+json media types, relationships/includes, sparse fieldsets, sorting, or error objects. If our roadmap is "become JSON:API compliant," this package covers roughly the pagination slice and nothing else; a full framework (e.g. Laravel JSON:API) would be the strategic bet. If our need is "our clients expect page[number]/page[size] and a links object," this is a near-perfect fit with almost zero architectural surface area.

Integration feasibility. Very high. Composer install, Laravel auto-discovery, optional published config (max_results, default_size, parameter names, method_name, simple/cursor/fast toggles), then a mechanical swap of ->paginate() for ->jsonPaginate() at the endpoints we choose. It composes with existing where clauses and relation queries, and accepts per-call overrides for max/default size and even a pre-computed total. Because the method name is configurable, collision risk with existing macros is controllable. Estimated effort: hours for a pilot endpoint, days for a full rollout plus contract tests.

Technical risk. Low-to-moderate, and mostly bounded:

  • Compliance overstatement (highest risk). Stakeholders may read "JSON:API paginator" as "we are JSON:API compliant." Mitigate with an explicit scope note in the ADR: pagination convention only.
  • Behavioral edge cases are unverified. The README documents caps (max_results default 30) but not what happens on page[size]=1000 or page[number]=0 — clamping vs. a JSON:API-required 400. We must pin this down with tests before publishing a client-facing contract.
  • URL generation is environment-sensitive. v4 removed the base_url config as a design flaw (it overwrote the path, collapsing /api/users and /api/posts to the same URL). The replacement is URL::forceScheme('https') / URL::forceRootUrl(...) in a service provider — which means correct links depend on our proxy/TLS-termination configuration, not the package. This is the single most likely production surprise.
  • Upgrade churn. v3→v4 is breaking for anyone who used base_url; we should adopt v4 directly and skip the legacy path.
  • Data quality flags. "Dependents: 0" alongside 645 stars and a mature Spatie release history is almost certainly a metadata artifact — verify real adoption via Packagist download counts. The "last release 2026-08-07" timestamp should also be reconciled against the actual changelog cadence before we cite maintenance health to leadership.

Key questions.

  1. Is our goal full JSON:API compliance (→ evaluate a complete framework) or pagination convention alignment (→ this package)?
  2. Which consumers (web SPA, mobile, external partners) actually parse the links object, and do any depend on last/prev semantics that cursor mode changes?
  3. Does traffic terminate behind a load balancer or CDN, and is forceRootUrl/forceScheme already configured?
  4. Which endpoints page deep into large tables (>100k rows) where offset cost is real?
  5. Do any queries use DISTINCT or expensive joins that make the total count a bottleneck?
  6. Do we already have a published pagination contract, and is the client-side churn worth the standardization?

Integration Approach

Stack fit. Requires a Laravel application with Eloquent; PHP 8.x and Laravel 10/11-class versions are supported per the changelog. No database-specific assumptions beyond Laravel's paginators. Cursor pagination requires an ordered, unique-ish column set (Laravel's constraint, not the package's). Fast pagination is strictly optional and pulls in spatie/laravel-fast-paginate (or recognizes the hammerstone/aaronfrancis variants) — treat that as a separate, later decision.

Migration path. Adopt v4+ directly to avoid the base_url trap. Steps: (1) install and publish config with an explicit max_results/default_size we can defend to clients; (2) configure URL forcing in AppServiceProvider and validate generated links in staging behind the same proxy topology as production; (3) replace paginate() with jsonPaginate() endpoint-by-endpoint, starting with a single low-traffic read endpoint; (4) add contract tests asserting request parameter names and the links shape; (5) only then broaden.

Compatibility. The macro approach is additive, so existing page=-style consumers keep working on untouched endpoints — this enables a genuinely incremental, per-endpoint cutover rather than a flag day. Watch for: custom paginator subclasses or response transformers that assume numeric page, existing macros registered under the same name, and any tests asserting on meta/links keys. Cursor mode is a global config switch (use_cursor_pagination overrides use_simple_pagination), which is a real constraint — it cannot be scoped per endpoint via config alone, so mixing cursor and offset endpoints likely requires per-call handling or a deliberate single-strategy decision.

Sequencing.

  1. ADR: scope (pagination only), chosen parameter names, max page size, error behavior for invalid params.
  2. URL/proxy correctness spike + staging verification.
  3. Pilot endpoint + contract tests.
  4. Rollout to remaining read endpoints; publish changelog note for API consumers.
  5. Performance follow-up: cursor pagination for deep-offset endpoints, or use_fast_pagination where the DB is the bottleneck.
  6. Defer full JSON:API evaluation until a concrete client requirement exists.

Operational Impact

Maintenance. Very low. MIT license, Spatie-maintained, small dependency surface, semver releases and a conventional changelog. The recurring cost is Laravel major-version cadence: the changelog shows compatibility PRs landing promptly for Laravel 10 and 11 (including automated Laravel Shift PRs), which is a good signal but also means we should expect at least an annual dependency bump. Budget a few hours per Laravel upgrade. Pin the version and let Renovate/Dependabot surface releases.

Support. Upstream support is community/issue-tracker with a security disclosure email; there is no vendor SLA. For a package this small, that is acceptable — the code path is shallow and we can fork or vendor it if upstream stalls. Internally, ownership should sit with the API platform team, with the pagination contract documented in our public API reference so client teams have a single source of truth rather than reading the Spatie README.

Scaling. Two distinct concerns. Volume is fine — this is a query-shaping macro with negligible overhead. Depth is not: offset pagination degrades linearly with page number, and the package's default 30-row cap will silently limit large page-size requests. For high-traffic or deep-paging endpoints, plan on cursor pagination (best DB performance, but changes link semantics — no numeric last) or fast pagination (deferred join, transparent to clients, lowest migration cost). Note the documented limitation that the manual $total argument has no effect under cursor, simple, or fast pagination — a footgun if we adopt it as a workaround for expensive counts.

Failure modes.

  • Silent truncation: a client requesting page[size]=200 receives 30 rows with no error, reads it as a short page, and stops paging. Detect via contract tests and explicit docs.
  • Broken/duplicate links behind a proxy: wrong scheme or host yields pagination URLs pointing to the wrong origin — historically the base_url bug class. Detect with a staging smoke test that asserts full URL paths per endpoint.
  • Inconsistent page boundaries: concurrent inserts during offset paging cause duplicated or skipped rows. Acceptable for most read APIs; escalate to cursor where it matters.
  • Expensive totals: DISTINCT/join-heavy queries make the count the slowest part of the request. Mitigate with simple pagination (no total) where the UI doesn't need a page count.
  • Cursor rollout surprise: flipping the global config changes every endpoint's response shape at once. Treat as a breaking API change requiring versioning and client coordination.
  • Macro collision: a custom method registered as jsonPaginate is silently overridden or overrides. Verify in a boot test.

Ramp-up. Essentially zero for Laravel developers — the mental model is "paginate() but spec-shaped." Engineering onboarding is a paragraph in the API guide. The real ramp-up is on the consumer side: client teams need the parameter names, the page-size ceiling, and the paging-termination rule documented. Allocate a short enablement note plus updated OpenAPI examples as part of the rollout, not after.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style