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 Query Builder Laravel Package

spatie/laravel-query-builder

Build safe, flexible Eloquent queries from incoming API requests. Supports whitelisted filtering (partial/exact/scope/custom), sorting, includes, field selection, pagination, and grouped AND/OR filters—ideal for JSON:API-style endpoints with minimal boilerplate.

View on GitHub
Deep Wiki
Context7

Easily build Eloquent queries from API requests

Frequently asked questions about Laravel Query Builder
How do I enable filtering for a specific Eloquent model in a Laravel API endpoint?
Use `QueryBuilder::for(Model::class)->allowedFilters(['field1', 'field2'])->get()` in your controller. For partial matches, specify `AllowedFilter::partial('field')`. Example: `QueryBuilder::for(User::class)->allowedFilters(AllowedFilter::partial('name'))->get()`. This handles requests like `/users?filter[name]=John` safely.
Can I use this package with Laravel 8.x or older versions?
No, this package requires Laravel 9+ due to dependencies on newer Eloquent features. If you’re on Laravel 8 or older, check the GitHub issues for alternatives or consider upgrading. The package explicitly drops support for older versions.
How do I prevent SQL injection when using dynamic query parameters?
The package enforces whitelisting via `allowedFilters()`, `allowedSorts()`, and `allowedIncludes()`. Only explicitly allowed fields are processed. For example, `allowedFilters(['email', 'status'])` restricts input to those fields, blocking arbitrary SQL injection attempts.
Does this package support nested relationships (e.g., includes like `?include=posts.comments`)?
Yes, use `allowedIncludes(['posts', 'posts.comments'])` to enable nested eager loading. The package follows Laravel’s `with()` syntax and supports dot notation for deep relationships. Example: `QueryBuilder::for(User::class)->allowedIncludes('posts')->get()`.
How can I apply default values to query parameters (e.g., default sorting or filters)?
Use `defaultSorts(['created_at', 'desc'])` or `defaultFilters(AllowedFilter::exact('status', 'active'))`. These apply when no query parameters are provided. Example: `QueryBuilder::for(Product::class)->defaultSorts(['price', 'asc'])->get()` ensures `/products` sorts by price ascending by default.
Will this package work with Laravel Policies or Gates for authorization?
Yes, the package integrates seamlessly with Laravel’s authorization system. Use `QueryBuilder::for(User::class)->allowedFilters(['name'])->where(function ($query) { $query->where('active', true); })->get()` to combine dynamic queries with policy checks. The query builder respects all Eloquent constraints.
How do I test API endpoints using this package for edge cases (e.g., invalid filters or malformed requests)?
Test with `Http::fake()` and `QueryBuilder::for(Model::class)->allowedFilters(['field'])->get()`. Mock requests like `filter[field]=%` or `sort=invalid` to verify whitelisting works. Use PHPUnit assertions to check returned data matches expected constraints.
Can I use custom filters beyond basic partial/exact matches (e.g., date ranges or custom scopes)?
Absolutely. Implement the `AllowedFilter` interface or use `AllowedFilter::custom('scope_name')` to map query parameters to Eloquent scopes. Example: `allowedFilters(AllowedFilter::custom('active'))` triggers a `scopeActive()` method on your model.
How do I integrate this into all API routes without repeating code in every controller?
Create middleware: `public function handle(Request $request, Closure $next) { $response = $next($request); if ($request->is('api/*')) { $response->header('X-Query-Builder', 'Enabled'); } return $response; }`. Then use `QueryBuilder::for(Model::class)` in routes or controllers.
What’s the performance impact of dynamic includes or complex sorts on large datasets?
Nested includes or custom sorts can cause N+1 queries or slow SQL. Mitigate by using `with()` for default includes and `constrain()` to limit results early. Example: `QueryBuilder::for(Product::class)->allowedIncludes('reviews')->constrain(fn ($query) => $query->where('price', '>', 10))->get()`. Monitor with Laravel Debugbar or query logging.
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony