Laravel Query Builder

Scramble PRO demo
Learn about Query Builder support
In around 2 minutes

Spatie’s Laravel Query Builder is a great package that allows you to filter, sort and include eloquent relations based on a request. And because query parameter names follow the JSON API specification as closely as possible, this package is really a good tool when building APIs.

Scramble has Laravel Query Builder support as a part of Scramble PRO package. You can get Scramble PRO here: https://scramble.dedoc.co/pro. After purchasing, you will receive the license key to your email.

Installation

Installation instructions for `dedoc/scramble-pro`

Usage

If you already configured routes for Scramble, after you install Scramble PRO – you should be all set up. Scramble will generate the query parameters for Laravel Query Builder.

While on this documentation page I use query builders defined directly in controllers, Scramble can document various query builder setups:

  • query builders defined in route actions (you’ll see many examples of this throughout the documentation);
  • custom query builders that extend the QueryBuilder class (learn more);
  • query builders defined in other methods called within your route actions (useful when following the action pattern, etc.).

Documenting filters

To define filters, use allowedFilters method on a query builder instance.

Request
query Params
filter[name]
string
filter[created_at]
string
1
use Spatie\QueryBuilder\QueryBuilder;
2
use App\Models\Company;
3
4
class CompaniesController extends Controller
5
{
6
public function index()
7
{
8
$companies = QueryBuilder::for(Company::class)
9
->allowedFilters(['name', 'created_at'])
10
->get();
11
12
// ...
13
}
14
}

Adding description to the filter

Also, you can add more description to a filter by adding comments and PHPDoc annotations. @example annotation can be used to specify examples, @var to specify a type, and @format to specify a format.

Request
query Params
filter[name]
string
The name to filter a company by. Multiple values can be passed, separated via `,` (`Nike,Tesla`)
Example
Tesla
filter[created_at]
string<date>
The date of the creation of the company.
1
$companies = QueryBuilder::for(Company::class)
2
->allowedFilters([
3
/**
4
* The name to filter a company by. Multiple values can be passed, separated via `,` (`Nike,Tesla`)
5
* @example Tesla
6
*/
7
'name',
8
/**
9
* The date of the creation of the company.
10
* @format date
11
*/
12
'created_at',
13
])
14
->get();

Documenting sorts

To define allowed sorts, use allowedSorts method on a query builder instance.

When Scramble documents allowed sorts, it will make examples from the allowed values.

Request
query Params
sort
string
Available sorts are `name`, `created_at`. You can sort by multiple options by separating them with a comma. To sort in descending order, use `-` sign in front of the sort, for example: `-name`.
1
use Spatie\QueryBuilder\QueryBuilder;
2
use App\Models\Company;
3
4
class CompaniesController extends Controller
5
{
6
public function index()
7
{
8
$companies = QueryBuilder::for(Company::class)
9
->allowedSorts(['name', 'created_at'])
10
->get();
11
12
// ...
13
}
14
}

You can use defaultSorts (or defaultSort) method, to specify the default sort. Scramble will document it as well.

Request
query Params
sort
string
Available sorts are `name`, `created_at`. You can sort by multiple options by separating them with a comma. To sort in descending order, use `-` sign in front of the sort, for example: `-name`.
Default
-name
1
$companies = QueryBuilder::for(Company::class)
2
->allowedSorts(['name', 'created_at'])
3
->defaultSort('-name')
4
->get();

Documenting includes

You can allow including relationships using allowedIncludes method on a query builder.

Scramble support both passing them as a string (including a relationship, count, existence), or passing allowed includes as instances of Spatie\QueryBuilder\AllowedInclude class.

Request
query Params
include
string
Available includes are `jobs`, `jobsCount`, `jobsExists`, `employees_count`. You can include multiple options by separating them with a comma.
1
$companies = QueryBuilder::for(Company::class)
2
->allowedIncludes([
3
'jobs',
4
AllowedInclude::count('employees_count'),
5
])
6
->get();

Notice that when you pass a string into allowedIncludes, you will enable 3 possible includes: the relationship you’ve provided, the count of that related items, and their existence.

List companies
get
https://thebestblog.com/api/company
Request
query Params
include
string
Available includes are `jobs`, `jobsCount`, `jobsExists`. You can include multiple options by separating them with a comma.
1
use Spatie\QueryBuilder\QueryBuilder;
2
use App\Models\Company;
3
4
class CompanyController extends Controller
5
{
6
public function index()
7
{
8
$companies = QueryBuilder::for(Company::class)
9
->allowedIncludes([
10
'jobs',
11
])
12
->get();
13
14
/* ... */
15
}
16
}

If you want to allow including only the relationship but not its count or existence, use custom AllowedInclude and provide the IncludedRelationship include to it.

List companies
get
https://thebestblog.com/api/company
Request
query Params
include
string
Available includes are `jobs`, `people`. You can include multiple options by separating them with a comma.
1
use Spatie\QueryBuilder\QueryBuilder;
2
use App\Models\Company;
3
use Spatie\QueryBuilder\AllowedInclude;
4
use Spatie\QueryBuilder\Includes\IncludedRelationship;
5
6
class CompanyController extends Controller
7
{
8
public function index()
9
{
10
$companies = QueryBuilder::for(Company::class)
11
->allowedIncludes([
12
AllowedInclude::custom('jobs', new IncludedRelationship()),
13
AllowedInclude::custom('people', new IncludedRelationship()),
14
])
15
->get();
16
17
/* ... */
18
}
19
}

Documenting fields

You can enable a selection of specific fields using allowedFields method.

You can allow selecting the fields of the model instance being queried, as well as selecting fields of the included relations. When describing allowed fields of the included relations, Scramble will separate it into a different query parameter.

Request
query Params
fields
string
Available fields are `id`, `name`, `created_at`. You can include multiple options by separating them with a comma.
fields[jobs]
string
Available fields are `id`, `title`. You can include multiple options by separating them with a comma.
1
$companies = QueryBuilder::for(Company::class)
2
->allowedFields(['id', 'name', 'jobs.id', 'jobs.title', 'created_at'])
3
->get();

Custom Query Builder class

When you want to encapsulate the logic in a query class, you can do this by extending Spatie\QueryBuilder\QueryBuilder and configuring your query builder in a constructor.

This approach can be seen in Spatie’s Laravel Query Builder documentation, in a video about building Mailcoach.

Here is the example from this video and the resulting documentation. Here Laravel Query Builder is used for the API request params, and Laravel Data for the response.

Get email list subscribers
get
https://thebestblog.com/api/email-list-subscribers
List all the email list subscribers.
Request
query Params
per_page
integer
Default
15
filter[search]
string
Fuzzy search subscribers by `email`, `first_name`, `last_name`, and the assigned tags `name`.
sort
string
Available sorts are `created_at`, `unsubscribed_at`, `email`, `first_name`, `last_name`. You can sort by multiple options by separating them with a comma. To sort in descending order, use `-` sign in front of the sort, for example: `-created_at`.
Responses
200
·
OK
The paginated collection of `EmailListSubscriber`
Body
object
data
EmailListSubscriber[]
required
The list of items
+ Show properties
links
object[]
required
Generated paginator links.
+ Show properties
meta
object
required
+ Show properties
1
<?php
2
3
namespace App\Queries;
4
5
use Spatie\QueryBuilder\AllowedFilter;
6
use Spatie\QueryBuilder\QueryBuilder;
7
// ...
8
9
class EmailListSubscribersQuery extends QueryBuilder
10
{
11
public function __construct(EmailList $list)
12
{
13
$query = EmailListSubscriber::query()
14
->where('email_list', $list->id);
15
16
parent::__construct($query);
17
18
$this
19
->allowedSorts('created_at', 'unsubscribed_at', 'email', 'first_name', 'last_name')
20
->allowedFilters([
21
/**
22
* Fuzzy search subscribers by `email`, `first_name`, `last_name`, and the assigned tags `name`.
23
*/
24
AllowedFilter::custom('search', new FuzzyFilter([
25
'email',
26
'first_name',
27
'last_name',
28
'tags.name',
29
]))
30
]);
31
}
32
}
Scramble PRO
Comprehensive API documentation generation for Spatie’s Laravel Data, Laravel Query Builder, and other packages.