Weave Code
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 Filtering Laravel Package

indexzer0/eloquent-filtering

Filter Laravel Eloquent models using simple arrays and request data—no custom query spaghetti. Define allowed filters on your models, support complex search, and keep queries readable, maintainable, and easy to extend for APIs and dashboards.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Eloquent-Centric: Perfectly aligns with Laravel’s Eloquent ORM, reducing boilerplate for dynamic query filtering. Eliminates manual query-building logic (e.g., where(), orWhere() chains) in favor of declarative model-level definitions.
  • API-First Design: Ideal for RESTful APIs or admin dashboards where client-side filtering (e.g., frontend tables, GraphQL inputs) maps directly to backend queries.
  • Separation of Concerns: Encapsulates filter logic within models (allowedFilters()), decoupling business rules from controllers/routes. Supports Single Responsibility Principle (SRP).
  • Extensibility: Supports custom filter types (via FilterType enum) and JSON path queries (e.g., nested attributes), accommodating complex data structures.

Integration Feasibility

  • Low Friction: Requires minimal changes—only model-level annotations (use Filterable; allowedFilters()) and a single filter() method call on queries.
  • Backward Compatibility: Non-intrusive; existing queries remain functional. Can be adopted incrementally (e.g., start with simple =, <, > filters).
  • Validation Layer: Built-in filter validation prevents SQL injection and enforces allowed operations per model.

Technical Risk

  • Learning Curve: Team familiarity with Eloquent’s query builder is assumed. Developers must understand the FilterType syntax (e.g., $eq, $like:start).
  • Performance Overhead: Dynamic query building may introduce slight overhead for complex filters (e.g., deeply nested $or conditions). Benchmarking recommended for high-traffic endpoints.
  • Sorting Immaturity: Documentation warns of instability in sorting features; avoid reliance on this for production-critical paths.
  • JSON Path Complexity: Advanced use cases (e.g., options->languages.$jsonLength) require PostgreSQL/MySQL JSON extensions and may not work universally across databases.

Key Questions

  1. Database Support: Does your stack support JSON path queries (PostgreSQL/MySQL 5.7+) for nested filters?
  2. Filter Granularity: Should filters be model-wide or scoped to specific endpoints (e.g., API resources)?
  3. Validation Needs: Are there custom validation rules for filter inputs (e.g., sanitizing $like values)?
  4. Caching Strategy: How will filtered queries interact with query caching (e.g., Laravel’s query cache)?
  5. Testing Coverage: Are there existing tests for dynamic query scenarios that could be adapted to validate this package?

Integration Approach

Stack Fit

  • Laravel 10+: Native compatibility with Eloquent’s query builder and PHP 8.2 features (e.g., enums for FilterType).
  • APIs/GraphQL: Seamless integration with Laravel Sanctum, Passport, or Lighthouse for client-driven filtering.
  • Admin Panels: Works well with tools like Filament, Nova, or Backpack for dynamic table filtering.
  • Legacy Systems: Can wrap existing where() logic in a custom Filterable trait for gradual adoption.

Migration Path

  1. Phase 1: Simple Filters
    • Replace manual where() calls with Filter::field() for basic operations ($eq, $gt, $like).
    • Example:
      // Before
      User::where('status', 'active')->where('age', '>', 18);
      
      // After
      User::filter([
          ['type' => '$eq', 'target' => 'status', 'value' => 'active'],
          ['type' => '$gt', 'target' => 'age', 'value' => 18],
      ]);
      
  2. Phase 2: Model-Level Abstraction
    • Define allowedFilters() in models to centralize filter logic.
    • Example:
      class User extends Model implements IsFilterable {
          use Filterable;
      
          public function allowedFilters(): AllowedFilterList {
              return Filter::only(
                  Filter::field('status', [FilterType::EQUAL]),
                  Filter::field('age', [FilterType::GREATER_THAN])
              );
          }
      }
      
  3. Phase 3: Client Integration
    • Expose filter schema to frontend (e.g., via OpenAPI/Swagger) or use a library like Vue Good Table for dynamic UI filtering.
    • Validate incoming filter arrays with Laravel’s ValidatedRequest or API resources.

Compatibility

  • Database: Tested on PostgreSQL/MySQL; SQLite may lack JSON path support.
  • Caching: Works with Laravel’s query cache but may need custom tags for filtered queries.
  • Testing: Compatible with Pest/PHPUnit; mock filter() calls in unit tests.
  • Monitoring: Log filtered queries (e.g., toRawSql()) to debug performance issues.

Sequencing

  1. Proof of Concept: Implement 1–2 endpoints with critical filters (e.g., dashboard tables).
  2. Performance Testing: Measure impact on query execution time and database load.
  3. Documentation: Update API specs to include filter examples and validation rules.
  4. Rollout: Prioritize high-impact areas (e.g., search-heavy features) before full adoption.

Operational Impact

Maintenance

  • Pros:
    • Reduced Boilerplate: Eliminates repetitive where() logic, easing future changes.
    • Centralized Rules: Filter definitions live in models, making them easier to audit.
    • MIT License: No vendor lock-in; can fork or modify if needed.
  • Cons:
    • Dependency Management: Requires monitoring for updates (last release: 2026-04-02).
    • Debugging: Complex nested filters may obscure query generation (use toRawSql() for debugging).

Support

  • Community: Active GitHub repo (224 stars, CI/CD, tests) but limited dependents (0). Support may require self-service or contributor engagement.
  • Error Handling: Package provides validation but may need custom error messages for business logic (e.g., "Filter 'status' cannot be 'pending'").
  • Onboarding: Requires training on FilterType syntax and model annotations.

Scaling

  • Performance:
    • Optimizations: Use database indexes on filtered fields (e.g., status, age).
    • Pagination: Combine with Laravel’s paginate() to avoid large result sets.
    • Caching: Cache filtered query results for static data (e.g., cache()->remember()).
  • Load Testing: Simulate high-concurrency scenarios with mixed filter types to identify bottlenecks.
  • Database: Ensure JSON columns are indexed if using $jsonLength or nested filters.

Failure Modes

Risk Mitigation
Invalid Filters Use allowedFilters() to whitelist operations; validate inputs via Form Requests.
SQL Injection Package sanitizes inputs, but custom filter types may introduce risks.
Query Timeouts Limit complexity of nested $or/$and conditions; add query timeouts.
Database Incompatibility Test on target DB early; avoid JSON path queries on SQLite.
Caching Issues Avoid caching filtered queries with dynamic parameters; use cache tags.

Ramp-Up

  • Developer Onboarding:
    • Workshop: 1-hour session on FilterType syntax and model annotations.
    • Cheat Sheet: Document common filter patterns (e.g., date ranges, multi-field searches).
  • Documentation Gaps:
    • Add examples for:
      • Custom filter types (e.g., FilterType::CUSTOM('between')).
      • Integration with Laravel Scout or Algolia.
      • Handling polymorphic relationships in filters.
  • Tooling:
    • IDE Support: Create PHPStorm live templates for allowedFilters() and filter arrays.
    • API Docs: Auto-generate OpenAPI specs for filter endpoints using laravel-openapi.
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport