Laravel Query Builder

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
Before installing Scramble PRO, make sure to update dedoc/scramble
to at least 0.12.9
.
Add the private repository to the list of your repositories in composer.json
"repositories": [ { "type": "composer", "url": "https://satis.dedoc.co" }],
Now, add the package to the list of your dependencies:
"require": { "dedoc/scramble-pro": "^0.7.3", "dedoc/scramble": "^0.12.9",}
And run composer update
.
When running composer update, you will be prompted to provide your credentials for the repository website. These credentials will authenticate your Composer session as having permission to download the Scramble PRO source code. To avoid manually typing these credentials, you may create a Composer auth.json file and use your license key in place of the password:
{ "http-basic": { "satis.dedoc.co": { "username": "youremail@company.com", "password": "YOUR-KEY-000000" } }}
You may quickly create an auth.json file via your terminal using the following command.
composer config http-basic.satis.dedoc.co \ youremail@company.com \ YOUR-KEY-000000
You should not commit your application’s auth.json
file into source control!
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.
Documenting filters
To define filters, you can use allowedFilters
method on a query builder instance.
use Spatie\QueryBuilder\QueryBuilder;use App\Models\Company;
class CompaniesController extends Controller{ public function index() { $companies = QueryBuilder::for(Company::class) ->allowedFilters(['name', 'created_at']) ->get();
// ... }}
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.
$companies = QueryBuilder::for(Company::class) ->allowedFilters([ /** * The name to filter a company by. Multiple values can be passed, separated via `,` (`Nike,Tesla`) * @example Tesla */ 'name', /** * The date of the creation of the company. * @format date */ 'created_at', ]) ->get();}
Documenting sorts
To define allowed sorts, you can use allowedSorts
method on a query builder instance.
When Scramble documents allowed sorts, it will make examples from the allowed values.
use Spatie\QueryBuilder\QueryBuilder;use App\Models\Company;
class CompaniesController extends Controller{ public function index() { $companies = QueryBuilder::for(Company::class) ->allowedSorts(['name', 'created_at']) ->get();
// ... }}
You can use defaultSorts
(or defaultSort
) method, to specify the default sort. Scramble will document it as well.
$companies = QueryBuilder::for(Company::class) ->allowedSorts(['name', 'created_at']) ->defaultSort('-name') ->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.
$companies = QueryBuilder::for(Company::class) ->allowedIncludes([ 'jobs', AllowedInclude::count('employees_count'), ]) ->get();
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.
$companies = QueryBuilder::for(Company::class) ->allowedFields(['id', 'name', 'jobs.id', 'jobs.title', 'created_at']) ->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.
<?php
namespace App\Queries;
use Spatie\QueryBuilder\AllowedFilter;use Spatie\QueryBuilder\QueryBuilder;// ...
class EmailListSubscribersQuery extends QueryBuilder{ public function __construct(EmailList $list) { $query = EmailListSubscriber::query() ->where('email_list', $list->id);
parent::__construct($query);
$this ->allowedSorts('created_at', 'unsubscribed_at', 'email', 'first_name', 'last_name') ->allowedFilters([ /** * Fuzzy search subscribers by `email`, `first_name`, `last_name`, and the assigned tags `name`. */ AllowedFilter::custom('search', new FuzzyFilter([ 'email', 'first_name', 'last_name', 'tags.name', ])) ]); }}
<?php
namespace App\Http\Controllers\Api;
use App\Data\EmailListSubscriber;use App\Queries\EmailListSubscribersQuery;// ...
class EmailListSubscribersController extends Controller{ /** * Get email list subscribers. * * List all the email list subscribers. */ public function __invoke(Request $request, EmailList $list) { $subscribers = (new EmailListSubscribersQuery($list)) ->paginate($request->integer('per_page', 15));
return EmailListSubscriber::collect($subscribers, PaginatedDataCollection::class); }}