emmadonjo/laravel-filter
A lightweight Laravel package for adding clean, reusable filters to Eloquent queries. Define composable filter classes once, apply them from request parameters or manually, and keep controllers slim, query logic organized, and filtering behavior easy to test and extend.
Architecture fit: emmadonjo/laravel-filter is a single-purpose Laravel package that sits between HTTP request input and Eloquent query construction — the layer where most Laravel applications accumulate ad-hoc ->when($request->has(...)) clauses. That is a narrow, well-understood insertion point, and it does not require changes to models, routing, or the service container beyond package discovery. Fit is high for applications with read-heavy index endpoints and repetitive filtering logic; it is low value for projects with a small number of bespoke queries or those already standardized on a query-builder abstraction (Laravel Query Builder, Spatie's filter packages, or hand-rolled scopes). Overlap with existing tooling is the primary architectural decision, not the package's internals.
Integration feasibility: Composer-installable and Laravel-auto-discovered in the conventional case. Realistic effort is small-to-moderate: install, publish any config, then convert one representative endpoint as a pilot. The unknown that drives effort is the package's extension surface — whether custom filters are class-based, closure-based, or config-mapped — because that determines how much of our domain-specific filter logic we can express without forking.
Technical risk: The v1.0.0 tag is the headline signal. Moving off 0.0.x implies the maintainer is asserting semver stability, which materially lowers the risk of silent breaking changes on patch/minor upgrades — the dominant risk with pre-1.0 Laravel packages. The accompanying "fix static analysis issues" indicates an active quality gate, but not which tool or at what strictness. Residual risks: (1) bus factor — the release notes list a single contributor, and both PRs are from the same author, so this is effectively a one-maintainer project; (2) no evidence in the notes of test coverage, CI matrix, or supported Laravel/PHP version ranges; (3) security surface — filter input flows from user-controlled request parameters into query constraints, so the allow-listing and injection-safety design must be verified directly rather than inferred.
Key questions:
composer.json constraints for PHP and illuminate/*, and is there a CI matrix proving them?where semantics?Stack fit: Assumes a conventional Laravel application on Eloquent with form-request or inline request validation. It is a natural companion to API resource collections and paginated index endpoints. Applications using raw query builder, multi-tenant global scopes, or read replicas need explicit review, since a filter layer that rewrites where clauses can interact badly with global scopes and connection routing.
Migration path: This is additive, not a replacement. Sequence: (1) pin ^1.0 in a sandbox branch; (2) inventory existing filtering code across controllers and repositories to size the surface area; (3) port one high-traffic, low-risk index endpoint behind a feature flag; (4) compare generated SQL and result sets against the incumbent implementation for a shared fixture of request payloads; (5) expand endpoint by endpoint, retiring bespoke ->when() chains only after parity is demonstrated. No data migration is involved, which keeps the blast radius contained to request handling.
Compatibility: The 1.0.0 tag gives us a stable contract to code against going forward, but the notes do not state minimum Laravel/PHP versions. Confirm against our current framework version before committing — particularly if we are on an older LTS or an unreleased major. Also verify behavior under Octane if we run it, since long-lived workers expose any package-level static or container-singleton state.
Sequencing: Land the dependency and the pilot endpoint in one PR so the package never sits installed-but-unused. Follow with a documented convention (where filters are declared, naming rules, allow-list policy) before broad rollout — otherwise we get two competing filtering idioms in the codebase. Defer any fork or custom-driver work until the pilot proves the extension surface is sufficient.
Maintenance: Low ongoing code footprint — the package owns query construction, not persistence or state. The real maintenance cost is upgrade coupling: every Laravel major will require confirming this package has a compatible release, and with a single maintainer that timeline is outside our control. Budget for the possibility of vendoring or forking at the next framework major.
Support: No commercial support and no visible governance. Treat upstream as best-effort and establish an internal owner for the integration layer. Keep our filter declarations centralized so a fork remains a contained change.
Scaling: Query-filter packages are performance-neutral by construction — cost is entirely a function of the indexes behind the filtered columns. The genuine scaling risk is unbounded input: if arbitrary request keys map to where clauses, a client can generate expensive or non-sargable queries. Enforce an explicit allow-list and rate-limit index endpoints before this reaches production traffic.
Failure modes: (1) Malformed or hostile filter parameters producing errors or, worse, unintended query semantics — mitigate with validation and allow-listing at the boundary; (2) silent behavior change on a minor upgrade — mitigate by pinning ^1.0 and reading changelogs, and by having parity tests on the pilot endpoint; (3) abandonment upstream — mitigate via the centralized declaration convention and a documented fork path; (4) interaction with global scopes or tenancy filters — mitigate by asserting tenant isolation in tests, since a filter layer that rebuilds constraints is a plausible source of scope leakage.
Ramp-up: Minimal for anyone already fluent in Eloquent. Expect roughly half a day for the pilot endpoint including parity checks, plus a short internal write-up of the convention. The main onboarding cost is not the API but the discipline of the allow-list policy — make that part of the PR template rather than tribal knowledge.
Recommendation: Adopt for a bounded pilot on a single index endpoint. The 1.0.0 tag is a credible stability signal and the integration is reversible, but the single-maintainer profile and the absence of published compatibility and security details in the release notes mean we should validate the allow-listing and extension design hands-on before standardizing on it.
Note: this release's changelog is limited to the version bump and static-analysis fixes; the assessment above is based on the package's stated scope and conventions rather than verified implementation details, and should be revisited once the pilot confirms the open questions.
How can I help you explore Laravel packages today?