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

Eloquent Query Dsl Laravel Package

hongxunpan/eloquent-query-dsl

A fluent query DSL for Laravel's Eloquent ORM that lets you build database queries with a clean, chainable syntax. Simplifies complex filtering, sorting, and relationship queries into readable, expressive code for more maintainable models and repositories.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit This package sits at the request-parsing boundary of a Laravel application: it converts raw query-string input into a normalized pagination directive (page or cursor) and, for cursor mode, constructs the corresponding Illuminate\Pagination\Cursor instance. That is a narrow, well-placed responsibility and fits cleanly into the typical controller → form-request → query-builder chain. The 0.4.0 release keeps the package inside that boundary — it explicitly does not execute queries, enforce authorization, or shape responses — which is the right scoping decision for a shared package and means adopting cursor pagination does not force an architectural rework of repositories or resources.

The mutual exclusivity of page and cursor is the most consequential design choice. It gives the application a single, unambiguous pagination mode per request, which is far easier to reason about than a hybrid contract. The decision in QueryDsl::apply() to select mode strictly from original input keys (rather than post-parse/defaulted values) is exactly the kind of detail that prevents a class of subtle production bugs, and its inclusion in this release is a positive signal about the maintainers' understanding of their own failure surface.

Integration feasibility High. The release is additive: existing page-based APIs remain compatible, and cursor support is opt-in via a new sibling input. DslInputMap accepting custom cursor parameter names means we can align the wire contract with existing front-end conventions (e.g. after/before or a namespaced key) without touching the library or asking consumers to rename their parameters. Bidirectional next/previous support covers the common "load more" plus "go back" UI pattern without a second endpoint.

The main integration work is on our side of the boundary: the package produces a cursor, but we own the query. That means every endpoint we migrate needs its ordering to be deterministic and cursor-compatible (stable sort key, tiebreaker column), and the response payload must expose the cursor links the package emits. This is a per-endpoint task, not a one-time framework change.

Technical risk

  • Ordering correctness (highest risk). Cursor pagination is only correct when the sort order is total and stable. Endpoints with non-unique sort columns, user-configurable sorts, or ORDER BY RAND() will silently drop or duplicate rows. This risk is entirely in application code but will be attributed to "the pagination package" when it surfaces.
  • Mutual exclusivity handling. Clients that send both page and cursor need a defined, documented behavior (rejection vs. precedence). The release notes state they are mutually exclusive but do not state the resolution rule; we must confirm and encode it in our API contract tests.
  • Parser-default regression class. The QueryDsl::apply() fix indicates this bug class existed. We should add our own regression tests around inputs where validation or casting injects default values, so the guarantee is pinned from the consumer side too.
  • Compatibility ceiling. PHP 8.0–8.3 and Illuminate 9–12 is a reasonable matrix today, but PHP 8.4 and any future Laravel major are outside the tested envelope. This is a maintenance watch item rather than a present risk.
  • Low intrinsic risk otherwise. PHPStan level 8, a passing full CI matrix, security audit, and a modest but non-trivial test suite (35 tests / 80 assertions) are adequate signals for a package of this scope at a 0.x version.

Key questions

  1. When a request supplies both page and cursor, does the package throw, ignore one, or apply a precedence rule? Is that behavior documented and covered by tests?
  2. What is the exact shape of the structured cursor output (link objects, position semantics, presence of previous when at the first page)?
  3. Is position intended for production clients or strictly a debugging aid? If it is client-visible, is it opaque/stable enough to contract?
  4. Does the package validate that the cursor was issued for the same ordering/query shape, or is that entirely the application's responsibility?
  5. What is the support horizon and release cadence expectation given the 0.x version number — can we depend on it for a multi-year product?
  6. Are invalid/expired/tampered cursors distinguishable in the error surface, so we can map them to a 400 rather than a 500?

Integration Approach

Stack fit Direct fit for a Laravel 9–12 application on PHP 8.0–8.3. No new runtime dependencies are implied beyond Illuminate, and the package operates purely on request input and cursor construction, so it introduces no coupling to our persistence layer, queue, or cache. It is agnostic to whether we use Eloquent, the query builder, or a read replica — consistent with the stated boundary that query execution stays in the application.

Migration path Incremental and low-friction, because page-based behavior is unchanged:

  1. Pin to ^0.4 in a branch and let existing page endpoints run untouched to confirm no behavioral drift.
  2. Introduce cursor mode on one new or low-traffic endpoint first, with a fixed, deterministic sort.
  3. Once the cursor contract and response shape are validated, migrate high-traffic list endpoints where offset pagination cost is actually hurting (deep pages, large tables).
  4. Leave small/admin endpoints on page mode indefinitely — there is no requirement to converge.

No data migration, no schema change, and no client breaking change is required. The only client-facing change is additive: new optional cursor parameters and new response fields on endpoints we choose to migrate.

Compatibility Existing page-based consumers are unaffected by design, and DslInputMap's custom cursor parameter names let us avoid colliding with any existing query keys. The one compatibility item to verify is the mutual-exclusivity resolution rule, since a client that already sends a stray page parameter alongside a new cursor parameter would hit it. We should gate rollout behind our own contract tests rather than relying solely on the package's suite.

Version risk is manageable but real: 0.x semver means minor bumps may carry behavior changes. We should pin exactly, review changelogs on upgrade, and treat the package as a candidate for vendoring or a thin internal adapter if the surface we use is small.

Sequencing

  1. Spike (small): confirm both-parameters behavior, cursor output shape, and position semantics against a real endpoint.
  2. Contract tests first: encode the mode-selection rule and cursor error mapping in our own test suite.
  3. Ordering audit: for each candidate endpoint, verify a total, stable sort key exists; add a unique tiebreaker where it does not.
  4. Pilot endpoint: ship cursor mode behind a feature flag, compare result sets against the page-based implementation for identical queries.
  5. Response layer: extend resources/serializers to emit cursor links consistently across migrated endpoints.
  6. Progressive rollout by endpoint, with page mode retained as fallback.

Operational Impact

Maintenance Low and predictable. Upgrades are pin-and-review, and the package's scope means changelogs are short and readable — this release note is itself a good example. The real maintenance load is not the dependency; it is the accumulated set of cursor-paginated endpoints, each of which carries an implicit invariant (stable ordering). We should document that invariant in our internal API guidelines, because it will be violated by future contributors who did not read this release note.

Budget a small recurring effort for compatibility tracking: PHP 8.4 and the next Laravel major will eventually need either an upstream release or a decision to fork. Given the package's narrow surface, forking would be cheap if the maintainer stalls.

Support Support burden shifts rather than grows. Cursor pagination eliminates a whole class of "page 400 returns different rows than page 1" complaints and reduces load from deep offset scans. It introduces a new class: "invalid or expired cursor" and "why did I get a 400 on my cursor." That is manageable if the error taxonomy is clean and we map cursor failures to explicit client errors with a documented recovery path (drop the cursor and restart from the first page).

Front-end teams need a short brief: cursors are opaque, must be echoed back verbatim, and are not bookmarkable across differing sort orders. That one page of documentation prevents most of the ticket volume.

Scaling Net positive. Shifting heavy list endpoints from offset to cursor pagination removes the OFFSET n sequential-scan cost that degrades badly on large tables and high page depths, and it avoids the read-replica inconsistency that plagues deep offset pagination when replicas lag. The mutual exclusivity rule also keeps query plans simple — one pagination strategy per request, no branching in the hot path.

The remaining scalability question is application-side: cursor queries need the right composite index on (sort_column, id) to stay fast. That is our indexing work, and it should be part of each endpoint's migration checklist.

Failure modes

  • Silent data loss from unstable sort — the most damaging failure, and the least visible: rows are neither erroring nor obviously missing. Mitigation: mandatory stable-sort review plus a pilot comparison against page mode.
  • Sort-order drift — a cursor issued under one ordering replayed against another produces wrong results. Mitigation: encode ordering in the cursor if the package permits, or bind cursors to a sort token at the application layer.
  • Both parameters supplied — outcome depends on undocumented resolution; if it silently picks one, clients may get unexpected pages. Mitigation: contract test and explicit API documentation.
  • Parser-default mode selection — the exact defect class addressed by the QueryDsl::apply() change; low residual risk but worth pinning with a consumer-side regression test.
  • Tampered or malformed cursor — must fail as a clean 4xx, not surfacing as an unhandled exception. Mitigation: explicit exception-to-response mapping in the app's handler.
  • Upstream 0.x breaking change — mitigated by exact pinning and changelog review on upgrade.

None of these are library defects; all are integration-discipline items, which is the expected profile given the package's deliberately narrow boundary.

Ramp-up Fast for backend engineers already familiar with Laravel's CursorPaginator — the mental model transfers directly, and the package is a thin input-normalization layer on top of it. Expect roughly a day to become productive, plus the pilot-endpoint work to internalize the ordering invariant.

Front-end ramp-up is a few hours: consume next/previous from the response, echo cursor parameters, handle the restart-on-invalid-cursor path, and understand that position is a debug aid rather than a stable client contract.

Overall recommendation: adopt. This release adds a genuinely useful capability with no breaking changes, a credible CI and static-analysis story, and — importantly — a clearly stated boundary that keeps the hard parts (query execution, authorization, response shape) where they belong. Approve for a pilot endpoint, gate wider rollout on the both-parameters behavior being confirmed and on a completed ordering audit per endpoint.

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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route