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

Laravel Query Builder Laravel Package

spatie/laravel-query-builder

Safely build Eloquent queries from incoming API requests. Allowlist filters, sorts, includes, and fields; supports partial/exact and custom filters, nested relationships, relation counts, and default values. Works with existing queries for clean, consistent endpoints.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Pros:

    • API-Driven Querying: Aligns perfectly with RESTful API design, enabling dynamic filtering, sorting, and field selection via query parameters. Reduces boilerplate in API controllers by centralizing query logic.
    • Eloquent Integration: Seamlessly integrates with Laravel’s Eloquent ORM, leveraging existing scopes, relationships, and query builder methods. Minimal disruption to existing database interactions.
    • Granular Control: Supports fine-grained configuration (e.g., allowedFilters, allowedSorts) to enforce security and performance boundaries (e.g., preventing SQL injection or unintended data exposure).
    • Composability: Works with pre-built queries (e.g., QueryBuilder::for($existingQuery)), enabling incremental adoption in legacy systems.
    • Performance Optimizations: Features like beginsWith/endsWith filters and field selection reduce payload size and improve query efficiency.
  • Cons:

    • Abstraction Overhead: Introduces an additional layer between API requests and raw SQL, which may complicate debugging or require familiarity with the package’s internals.
    • Dynamic Nature: Runtime query construction (e.g., via filter[] parameters) can make static analysis or caching harder without explicit opt-ins (e.g., caching strategies for filtered queries).
    • Complexity for Edge Cases: Advanced features (e.g., custom filters, nested relationships) may require deeper understanding or custom code, increasing maintenance burden.

Integration Feasibility

  • Laravel Ecosystem: Designed specifically for Laravel, with zero configuration required beyond installation. Plays well with Laravel’s service container, middleware, and testing tools.
  • API Layer: Ideal for API-first applications (e.g., GraphQL, REST) where client-driven filtering/sorting is desired. Can coexist with Laravel’s built-in API resources or standalone controllers.
  • Existing Codebase:
    • Greenfield: Trivial to adopt in new projects; aligns with Laravel conventions.
    • Brownfield: Requires careful analysis of existing query logic. May need refactoring to extract reusable query builders or scopes for compatibility.
  • Database Agnostic: Works with any database supported by Laravel (MySQL, PostgreSQL, SQLite, etc.), but performance characteristics (e.g., LIKE vs. = queries) may vary.

Technical Risk

  • Security:
    • SQL Injection: Mitigated by the package’s design (input validation, whitelisting via allowedFilters), but misconfiguration (e.g., allowing raw SQL input) could introduce risks.
    • Data Exposure: Field selection (fields[]) must be explicitly configured to avoid leaking sensitive columns.
    • Dependency Risk: Low, given the package’s maturity (4.4K stars, active maintenance) and MIT license.
  • Performance:
    • N+1 Queries: Eager loading via include[] prevents N+1 issues but requires explicit relationship definitions.
    • Query Bloat: Unrestricted dynamic filters/sorts could lead to inefficient queries. Mitigate via allowed* methods and query profiling.
  • Compatibility:
    • Laravel Version: Tested with Laravel 7+ (as of 2026). May require adjustments for older versions or custom Laravel forks.
    • Third-Party Packages: Potential conflicts with packages that modify Eloquent queries (e.g., query loggers, debug bars). Test thoroughly.
  • Testing:
    • Unit Testing: Query builders can be tested in isolation using Laravel’s mocking tools.
    • Integration Testing: Critical for edge cases (e.g., malformed requests, complex relationships). Use Laravel’s HTTP tests.

Key Questions

  1. Adoption Scope:
    • Will this replace all API queries, or only specific endpoints? Partial adoption may require hybrid approaches (e.g., mixing QueryBuilder with manual queries).
  2. Security Boundaries:
    • How will allowedFilters/allowedSorts be configured? Will roles/permissions dynamically restrict these (e.g., admin vs. public API)?
  3. Performance Trade-offs:
    • Are there queries where dynamic filtering/sorting is unnecessary? Consider disabling the package for static queries.
  4. Monitoring:
    • How will slow queries (e.g., due to unoptimized LIKE filters) be detected and addressed? Integrate with Laravel Debugbar or query logging.
  5. Documentation:
    • Does the team have experience with Spatie packages? If not, budget time for ramp-up (e.g., reviewing docs, testing edge cases).
  6. Future-Proofing:
    • Are there plans to extend the package (e.g., adding pagination, caching layers)? The package’s API is stable, but custom extensions may be needed.

Integration Approach

Stack Fit

  • Primary Use Case: API Layer (REST/GraphQL) in Laravel applications.
  • Complementary Tools:
    • API Resources: Pair with Laravel’s API resources for field selection and transformation.
    • Rate Limiting: Combine with Laravel’s rate limiting middleware to prevent abuse of dynamic queries.
    • Caching: Use Laravel’s cache middleware or QueryBuilder’s caching features (if extended) for filtered/sorted results.
    • Validation: Integrate with Laravel’s validation pipeline to sanitize input before query construction.
  • Alternatives Considered:
    • Manual Query Building: More verbose but offers finer control. Justify QueryBuilder adoption with reduced boilerplate and consistency.
    • GraphQL: If using GraphQL, consider packages like spatie/laravel-query-builder for GraphQL resolvers (though this package is REST-focused).
    • Database-Level Filtering: Tools like PostgreSQL’s JSONB or Elasticsearch for complex searches, but adds operational overhead.

Migration Path

  1. Pilot Phase:
    • Start with non-critical endpoints (e.g., read-only, low-traffic APIs).
    • Example: Replace a controller like:
      public function index(Request $request) {
          return User::where('active', true)
              ->when($request->has('name'), fn($q) => $q->where('name', 'like', '%'.$request->name.'%'))
              ->get();
      }
      
      with:
      public function index() {
          return QueryBuilder::for(User::class)
              ->allowedFilters('name')
              ->allowedFilters(AllowedFilter::exact('active'))
              ->get();
      }
      
  2. Incremental Rollout:
    • Group endpoints by feature (e.g., all "User" API routes).
    • Use feature flags to toggle QueryBuilder usage.
  3. Refactoring Existing Logic:
    • Extract reusable query builders or scopes for complex logic.
    • Example:
      // Before: Scattered in controllers
      User::whereHas('posts', fn($q) => $q->where('published', true));
      
      // After: Centralized in QueryBuilder
      QueryBuilder::for(User::class)
          ->allowedFilters(AllowedFilter::belongsTo('posts', 'published_posts'))
          ->get();
      
  4. Deprecation:
    • Phase out manual query logic in favor of QueryBuilder once all endpoints are migrated.
    • Use Laravel’s deprecation helpers to warn developers.

Compatibility

  • Laravel Versions: Tested with Laravel 7+. For older versions, check the UPGRADING.md guide.
  • PHP Versions: Requires PHP 8.0+. Ensure your environment meets this requirement.
  • Database Drivers: Compatible with all Laravel-supported databases, but performance may vary (e.g., LIKE vs. ILIKE in PostgreSQL).
  • Customizations:
    • Middleware: Create middleware to enforce QueryBuilder usage or add default configurations.
    • Service Providers: Extend the package’s configuration or bind custom filter/sort handlers.
    • Testing: Use Laravel’s QueryBuilder facade in tests to mock dynamic queries.

Sequencing

  1. Setup:
    • Install the package: composer require spatie/laravel-query-builder.
    • Publish config (if needed): php artisan vendor:publish --provider="Spatie\QueryBuilder\QueryBuilderServiceProvider".
  2. Configuration:
    • Define global defaults in config/query-builder.php (e.g., disable exceptions for invalid filters).
    • Set up allowed filters/sorts per model or endpoint.
  3. Development:
    • Replace manual queries with QueryBuilder in controllers.
    • Test edge cases (e.g., malformed requests, empty results).
  4. Deployment:
    • Roll out to staging first, monitor for errors or performance regressions.
    • Gradually enable in production.
  5. Optimization:
    • Profile queries to identify slow filters/sorts (e.g., LIKE on large tables).
    • Add indexes or adjust allowedFilters to use exact matches where possible.

Operational Impact

Maintenance

  • Pros:
    • Reduced Boilerplate: Centralized query logic simplifies maintenance (e.g., adding a new filter requires updating one place).
    • Consistent Behavior: Enforces uniform query patterns across the codebase.
    • Documentation: Clear separation of allowed vs
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