matthenning/eloquent-api-filter
A Laravel package for turning request query parameters into Eloquent API filters, helping keep controllers clean and expose flexible, readable filtering for API endpoints with minimal configuration.
Summary position: Low-maturity, single-maintainer package in a functionally commoditized space, carrying a copyleft license that is incompatible with most commercial Laravel product baselines. The technical capability is real but thin; the strategic risk is disproportionate to the value delivered. Recommendation: do not adopt into product code without a legal gate; treat as a reference implementation or replace with a permissively licensed equivalent.
| Dimension | Assessment | Rating |
|---|---|---|
| Architecture fit | Adequate for CRUD list endpoints; leaks schema into API contract | Medium |
| Integration feasibility | Composer-native, likely trivial to install | High |
| Maintenance maturity | 10 stars, one maintainer, last release 2024-01-22 | Very Low |
| License risk | GPL-3.0, strong copyleft, viral-by-default posture | Critical |
| Security surface | Request param → query builder; allowlisting semantics unverified | High |
Architecture fit. The package decorates the Eloquent query builder from the HTTP request, which is a natural fit for a Laravel MVC / API-resource architecture and requires no deviation from framework conventions. The architectural concern is where it sits: it couples the public API contract directly to database column names and operators. That means column renames become breaking API changes, sensitive columns become externally addressable unless explicitly allowlisted, and the filter grammar becomes a de facto versioned interface with no versioning mechanism. For an internal or short-lived service this is acceptable; for a public or partner-facing API it is a liability that will be paid for at the first schema migration.
Integration feasibility. Expected to be a standard Composer install with package auto-discovery and a model-side trait or scope. The practical friction is dependency resolution: the last release predates Laravel 11, so illuminate/* constraints may block or require --ignore-platform-reqs-style workarounds on current Laravel. Verify against your actual pinned versions before assuming it installs cleanly.
Technical risk.
is_admin, email, internal flags) by observing result sets — a disclosure channel that does not require the column to be serialized in the response.Key questions for the maintainer / spike.
Stack fit. Assumes a conventional Laravel + Eloquent stack on PHP 8.x. No framework exotica, no queue or cache dependency, no service infrastructure — it is a query-builder concern only. It will not fit non-Eloquent data access (raw query builders, repository abstractions over multiple sources, or read models backed by something else), and retrofitting it into those is not worthwhile.
Build-vs-buy. This is the central decision, and it should be framed honestly as buy vs. borrow vs. build:
| Option | License | Maturity | Verdict |
|---|---|---|---|
matthenning/eloquent-api-filter |
GPL-3.0 | 10 stars, 1 maintainer | Reference only |
spatie/laravel-query-builder |
MIT | High adoption, active | Preferred |
Hand-rolled scopeFilter + allowlist |
In-house | Owned | Viable for small surfaces |
The capability here is ~150 lines of well-understood code. The package's entire value proposition is avoiding that writing. Against a blocking license and a single-maintainer dependency, the arithmetic does not favor adoption.
Migration path. If already present somewhere in the codebase, do not rip-and-replace blindly. Wrap it: define an internal FilterableQuery interface or a base query-object that owns allowlist declaration and operator parsing, and make the package one implementation behind it. That converts a future swap into a one-file change and gives you a place to enforce deny-by-default regardless of what the package does natively. If it is not yet present, the migration path is simply don't — adopt the MIT alternative and port the endpoint contract.
Compatibility. Two concrete checks before any code is written: (1) composer why-not against your pinned Laravel and PHP versions, since a January 2024 release likely predates Laravel 11/12 and may not have been re-tagged for PHP 8.3/8.4 deprecations; (2) whether the package's filter grammar can express the queries your existing API consumers already send — a divergent grammar is a breaking change for clients and the hidden cost of any swap.
Sequencing.
Do not parallelize steps 1 and 2 — sequencing the legal gate first avoids spending engineering days on a package you cannot ship.
Maintenance. Effectively unmaintained in any commercial sense. Plan to vendor, fork, or replace within a 12–24 month horizon. A fork is legally straightforward under GPL but converts an external dependency into an internal one you now own, staff, and patch — which is strictly worse than writing the equivalent in-house under your own license. There is no deprecation policy to plan upgrades against, so Laravel major upgrades become a bespoke compatibility exercise each cycle.
Support. Community-only via GitHub issues, with no SLA, no security contact policy, and a tiny user base that will not surface bugs before you do. Escalation path is "read the source yourself." For a production dependency with revenue attached, that is not a supportable posture.
Scaling. Filtering is delegated to the database, so scaling is a function of indexing discipline rather than the package. Two structural costs to budget for: unbounded filtering and sorting on unindexed columns produce full table scans that will not appear in application metrics until the table is large; and relation filtering, if implemented via lazy loading rather than joins, reintroduces N+1 under exactly the query shapes most likely to be hit by API clients. Mitigations are conventional — cap the number of active filters, restrict sortable columns to indexed ones, require pagination, and add per-route rate limits — but they must be built by you, since the package does not supply them.
Failure modes.
| Failure | Trigger | Blast radius | Detection |
|---|---|---|---|
| License finding at audit | Pre-release legal/security review | Release blocker, rework | Legal review — too late if deferred |
| SQL injection via operator | Crafted filter string | Data breach | Pen test / code review only |
| Information disclosure | Probing hidden columns | Data exposure | Requires log analysis of query shapes |
| Silent ignore of bad filter | Client typo or API drift | Wrong results, no error | Client-side reports; hard to trace |
| Unindexed scan | Popular filter on non-indexed column | P99 latency, DB saturation | Slow query log |
| Dependency resolution block | Laravel major upgrade | Upgrade stall | Build failure |
| Abandonment | Maintainer moves on | Permanent fork liability | Periodic registry check |
The two most dangerous rows are the ones that fail quietly — disclosure and silent filtering — because neither generates an alert and both surface as a client complaint months later.
Ramp-up. The library surface is small; a mid-level Laravel engineer is productive in under a day and fully fluent in a week. The learning cost is not the API — it is the conventions you must invent around it: the allowlist declaration pattern, the operator grammar you expose, error semantics for invalid filters, and the API documentation that describes all of it. Budget roughly a day of integration effort and 3–5 days of engineering plus review for the security posture and governance layer the package does not provide. The dominant cost is the legal gate and the ongoing ownership of a fork you did not want.
Bottom line for planning. Do not put this on a delivery critical path. Open the legal review, spike the MIT alternative against the same contract, and reserve adoption for the narrow case where an internal-only, non-distributed service needs filtering in a single sprint and the license has been explicitly cleared in writing.
How can I help you explore Laravel packages today?