Laravel 12 with Spatie Laravel-Query-Builder: A Complete Guide

Author

Kritim Yantra

Apr 16, 2025

Laravel 12 with Spatie Laravel-Query-Builder: A Complete Guide

In this blog post, we'll explore how to use the Spatie Laravel-Query-Builder package in Laravel 12 to create powerful, filterable API endpoints with minimal code. This package simplifies complex query building while maintaining clean, readable syntax.


Table of Contents

  1. Introduction to Spatie Laravel-Query-Builder
  2. Installation & Setup
  3. Basic Filtering
  4. Advanced Filtering Techniques
  5. Sorting Results
  6. Including Relationships
  7. Pagination & Customization
  8. Field Selection
  9. Advanced Features & Tips
  10. Conclusion

1. Introduction to Spatie Laravel-Query-Builder

The Spatie Laravel-Query-Builder package provides an elegant way to:

  • Filter data via URL parameters (?filter[name]=John).
  • Sort results (?sort=name,-created_at).
  • Include relationships (?include=posts,comments).
  • Select fields (?fields[users]=id,name).
  • Paginate automatically with query-string preservation.

It's perfect for building RESTful APIs with complex filtering requirements.


2. Installation & Setup

Step 1: Install Laravel 12

If you don’t have Laravel 12 installed:

composer create-project laravel/laravel query-builder-demo
cd query-builder-demo

Step 2: Install Spatie Laravel-Query-Builder

composer require spatie/laravel-query-builder

Step 3: Create a Model & Controller

php artisan make:model Post -mcr

Run migrations:

php artisan migrate

3. Basic Filtering

Basic Query Building

In your controller (PostController.php):

use Spatie\QueryBuilder\QueryBuilder;

public function index()
{
    $posts = QueryBuilder::for(Post::class)
        ->allowedFilters(['title', 'author'])
        ->get();

    return response()->json($posts);
}

Now you can filter via URL:

/posts?filter[title]=Laravel&filter[author]=John

Exact vs. Partial Matching

By default, filters use exact matching. For partial matches:

->allowedFilters(['title', AllowedFilter::partial('author')])

Now ?filter[author]=jo matches "John".


4. Advanced Filtering Techniques

Custom Filter Logic

use Spatie\QueryBuilder\AllowedFilter;

->allowedFilters([
    AllowedFilter::callback('published_after', function ($query, $value) {
        $query->where('published_at', '>=', $value);
    })
])

Usage:

/posts?filter[published_after]=2024-01-01

Scope Filters

Apply model scopes directly:

->allowedFilters([
    AllowedFilter::scope('popular'),
])

In Post.php:

public function scopePopular($query)
{
    return $query->where('views', '>', 1000);
}

Usage:

/posts?filter[popular]=true

5. Sorting Results

Basic Sorting

->allowedSorts(['title', 'created_at'])

Usage:

/posts?sort=title,-created_at  // (Descending)

Custom Sorting Logic

->allowedSorts([
    AllowedSort::custom('length', new StringLengthSort()),
])

See official docs for custom sort classes.


6. Including Relationships

Eager Loading

->allowedIncludes(['author', 'comments'])

Usage:

/posts?include=author,comments

Nested Relationships

->allowedIncludes(['author.profile'])

Now ?include=author.profile works.


7. Pagination & Customization

Automatic Pagination

$posts = QueryBuilder::for(Post::class)
    ->paginate();

URL:

/posts?page=2

Customizing Pagination

->paginate(perPage: 15)

Or via request:

/posts?page=2&per_page=15

8. Field Selection

Sparse Fieldsets

->allowedFields(['id', 'title'])

Usage:

/posts?fields[posts]=id,title

Nested Field Selection

/posts?include=author&fields[author]=name

9. Advanced Features & Tips

Appending Default Filters

QueryBuilder::for(Post::class)
    ->defaultFilter('status', 'published')

Combining with API Resources

return PostResource::collection($query->paginate());

Performance Optimization

  • Use allowedFilters() carefully to avoid slow queries.
  • Add indexes to frequently filtered columns.

10. Conclusion

The Spatie Laravel-Query-Builder package supercharges Laravel APIs by:
Simplifying complex filtering with URL parameters.
Reducing boilerplate code for sorting & relationships.
Maintaining clean, readable syntax.
Working seamlessly with pagination & resources.

Perfect for admin panels, public APIs, or data-heavy applications.

Happy query building! 🚀

Tags

Laravel Php

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts