Skip to main content
Version: 11.x

Query Parameters

Users often need to control the response data, thus the apiato supports some useful and common query parameters:

Sorting & Ordering

(provided by the L5 Repository)

The ?sortedBy= parameter is usually used with the orderBy parameter.

By default, the orderBy sorts the data in Ascending order, if you want the data sorted in Descending order, you can add &sortedBy=desc.

?orderBy=id&sortedBy=asc
?orderBy=created_at&sortedBy=desc
?orderBy=name&sortedBy=asc

Accepts:

  • asc for Ascending.
  • desc for Descending.

Using the RequestCriteria

(provided by the L5 Repository)

RequestCriteria is a standard Criteria implementation. It enables filters to perform in the repository from parameters sent in the request.

You can perform a dynamic search, filter the data and customize the queries.

Apiato provides addRequestCriteria() & removeRequestCriteria() methods which are available in both Actions and Tasks provided by the Apiato\Core\Traits\HasRequestCriteriaTrait.

Usage example:

class GetAllAdminsAction extends Action
{
public function run()
{
return app(GetAllUsersTask::class)->addRequestCriteria()->run();
// return app(GetAllUsersTask::class)->removeRequestCriteria()->run();
}
}

Using removeRequestCriteria() is only meaningful if you have applied RequestCriteria using below methods, otherwise RequestCriteria is not applied automatically thus you don't need to remove it if it is not needed.

To use the Criteria in your repository, you can add a new criteria in the boot method of your repository, or directly use in your controller, in order to filter out only a few requests. Read more about it here.

Searching

If the RequestCriteria is enabled on a route then the ?search= parameter can be applied to GET HTTP requests on that specific route.

For the search to work you need to define which fields from the model can be searchable.
In your repository set $fieldSearchable with the name of the fields to be searchable or a relation to fields.

protected $fieldSearchable = [
'name',
'email',
'product.name'
];

You can set the type of condition which will be used to perform the query, the default condition is "="

protected $fieldSearchable = [
'name'=>'like',
'email', // Default Condition "="
'your_field'=>'condition'
];
?search=John
?search=name:John
?search=name:John%20Doe

Notice should replace the space with %20.

Space should be replaced with %20 (search=keyword%20here).

Search any field for multiple keywords

api.domain.test/endpoint?search=first keyword;second keyword

Search in a specific field

api.domain.test/endpoint?search=field:keyword here

Search in specific fields for multiple keywords

api.domain.test/endpoint?search=field1:first field keyword;field2:second field keyword

Search Hashed IDs

If you have Hash ID enabled, and you want to search a hashed field (e.g. user ID) ?search=id:XbPW7awNkzl83LD6 you need to tell the RequestCriteria to decode it before it can be searched.
Let's say we have this search query ?search=id:XbPW7awNkzl83LD6;parent_id:aYOxlpzRMwrX3gD7;some_hashed_id:NxOpZowo9GmjKqdR. Then you have to update your addRequestCriteria method like this:

   app(GetAllUsersTask::class)->addRequestCriteria(null, ['id', 'parent_id', 'some_hashed_id'])->run();

By default, two things will be decoded:

  1. Single value search (e.g. search=something)
    This will only be decoded if it is a hash id so search=NxOpZowo9GmjKqdR will become search=1 but search=something will not be decoded and will stay same (search=something).
  2. The id field
    If you are searching only by id field, you do not need to add it to decode array above. This will be decoded ?search=id:XbPW7awNkzl83LD6 automatically.

Define query condition

api.domain.test/endpoint?search=field:keyword&searchFields=name:like

Checkout the Search Page for full implementation example.

?search=name:John&email:[email protected]
?search=name:John;email:[email protected]
?searchFields=name:like
?searchFields=email:=
?searchFields=name:like;email:=
?search=git&searchFields=url:like

Search Join:

By default, search makes its queries using the OR comparison operator for each query parameter.

api.domain.test/v1/endpoint?search=age:17;email:[email protected]

The above example will execute the following query:

SELECT * FROM users WHERE age = 17 OR email = '[email protected]';

In order for it to query using the AND, pass the searchJoin parameter as shown below:

api.domain.test/v1/endpoint?search=age:17;email:[email protected]&searchJoin=and

Filtering

?filter= parameter can be applied to any HTTP request and is used to control the response size, by defining what data you want back in the response.

Usage:

Return only ID and Status from that Model, (everything else will be returned as null).

api.domain.test/endpoint?filter=id;status

Example Response, including only id and status:

{
"data": [
{
"id": "0one37vjk49rp5ym",
"status": "approved",
"products": {
"data": [
{
"id": "bmo7y84xpgeza06k",
"status": "pending"
},
{
"id": "o0wzxbg0q4k7jp9d",
"status": "fulfilled"
}
]
},
"recipients": {
"data": [
{
"id": "r6lbekg8rv5ozyad"
}
]
},
"store": {
"data": {
"id": "r6lbekg8rv5ozyad"
}
}
}...

Note that the transformer, which is used to output / format the data is also filtered. This means, that only the fields to be filtered are present - all other fields are excluded. This also applies for all relationships (i.e., includes) of the object.

Pagination

(provided by the L5 Repository)

See Pagination.

Relationships (include)

(provided by the Fractal Transformer)

Include relationships for complex data structures.

Get an object with its relationships:

For this to work, your Transformer should have the relationships defined on it. Check the Transformers for more details on how to define such relationships.

You can include such relationships by adding the include query parameter with comma , separated names, like so:

?include=tags,user

It is also possible to

?include= parameter can be used with any endpoint if it is supported.

How to use it

Let's say there is a Driver and a Car object. Also, there is an /cars endpoint that returns all Car objects. The ?include parameter allows getting all cars with their respective drivers in one request by calling /cars?include=driver.

However, for this parameter to work, the CarTransformer, which handles the /cars endpoint should clearly define that it accepts driver as relationship ($availableIncludes in Transformer).

Nested Includes

It is also possible to request "nested includes". Extend the example from above. Imagine, that a Driver may also have a relationship to an Address object. You can access this information as well by calling ?include=driver,driver.address.

Of course, the address include is defined in the respective DriverTransformer that is used here.

Where to define the includes:

Every Transformer can have 2 types of includes $availableIncludes and $defaultIncludes:

    protected $availableIncludes = [
'products',
'store',
'recipients',
];

protected $defaultIncludes = [
'invoice',
];

$defaultIncludes will not be listed in the response, only the $availableIncludes will be.

Visit the Transformers page for more details.

Skip caching

(provided by the L5 Repository)

Note: You need to turn the Eloquent Query Caching ON for this feature to work. ELOQUENT_QUERY_CACHE=true in .env.

To run a new query and force disabling the cache on certain endpoints, you can use this parameter

?skipCache=true

It's not recommended to keep skipping cache as it has bad impact on the performance.

Configuration

Most of these parameters are provided by the L5 Repository and configurable from the Ship/Configs/repository.php file. Some of them are built in house, or inherited from other packages such as Fractal.

See the Query parameters from the User Developer perspective

  1. Generate the Default API documentation

  2. Visit the documentation URL

More details in the API Docs Generator page.

More Information

For more details on these parameters check out these links: