This package map some usual REST query filters to Eloquent scopes. This is mainly an extract of the filters present in andersao/l5-repository. but attachable to the model itself not via repositories. A big thanks to the previous contributors for their great work ;)
it consist of different scopes & an execution heap to ease the registration. you can register any scope individually or use the heap to register them all. head up: if you use them individually, the Request is a mandatory constructor parameter.
you can use qs to ease the parameters formatting
install the package
composer require goopil/eloquent-rest-filter
for laravel <= 5.3 add
\Goopil\RestFilter\RestScopeProvider::class
to use the config file
you can publish it with
php artisan vendor:publish --provider="Goopil\RestFilter\RestScopeProvider" --tag=config
To register all defined query Scopes, you can define the scopes for each query or on the controller to work on a routes basis.
use App\User;
use Goopil\RestFilter\RestScopes\Scopes\FullScope;
MyController extends Controller
{
public function __construct()
{
// global constructor registration
User::addGlobalScope(new FullScope);
}
public function index (MyCustomRequest $r)
{
// you can pass the current request if you use it in your context and specify
the separator used for this controller only
User::addGlobalScope(new FullScope($r, ';', '|'));
// or the request will automaticaly be fetched if none are provided.
User::addGlobalScope(new FullScope);
return response()->json([
data => User::all()
]);
}
}
manually
use Illuminate\Database\Eloquent\Model as Eloquent;
use Goopil\RestFilter\RestScopes\Scopes\FullScope;
MyModel extends Eloquent
{
public static function boot ()
{
parent::boot();
static::addGlobalScope(new FullScope);
}
}
via a trait
use Illuminate\Database\Eloquent\Model as Eloquent;
use Goopil\RestFilter\Contracts\Queryable;
MyModel extends Eloquent
{
use Queryable;
}
The parameters support array parameters.
http://exemple.com/api/v1/users?search[1]=John&search[2]=Tom
value | function |
---|---|
; |
delimit per field name and query value |
| |
delimit per field options |
the search feature make use of Goopil\RestFilter\Contracts\Searchable
.
this interface simply specify a searchable()
method on the model. That will return an array of fields to search into. Relations fields are supported.
By default or where clause ar implemented if you want to force a where close, you can add a !
on the comparison segments
static public function searchable()
{
return [
'id',
'active',
'username',
'email',
'firstname',
'lastname',
'roles.name',
'roles.slug',
'roles.description',
];
}
http://exemple.com/api/v1/users?search[]=John%20Doe
http://exemple.com/api/v1/users?search[roles.name]=administrator
http://exemple.com/api/v1/users?search[]=Johns;like
http://exemple.com/api/v1/users?search[email]=john@gmail.com;like
http://exemple.com/api/v1/users?search[name]=John%20Doe&search[email]=john@gmail.com
http://exemple.com/api/v1/users?search[name]=john&search;like&search[email].com;like
http://exemple.com/api/v1/users?search[name]=john&search;like&search[email].com;!like
http://exemple.com/api/v1/users?filter=id;name
name | type | format |
---|---|---|
filter | string | {field1} ; {value1} |
http://exemple.com/api/v1/users?filter=id;name&orderBy=id&sortedBy=desc
name | type | format |
---|---|---|
orderBy | string | {field1} |
sortedBy | string | {desc} |
http://exemple.com/api/v1/users?include=roles
http://exemple.com/api/v1/users?include=roles;sessions
http://exemple.com/api/v1/users?include=roles.permissions;sessions
name | type | format |
---|---|---|
include | string | {field1} ; {value1} |
The Goopil\RestFilter\Contracts\Paginable
rewrite the static all()
method
to parse the request for page
& perPage
params and call the paginate()
method instead if needed.
http://exemple.com/api/v1/users?page=1
http://exemple.com/api/v1/users?page=1&perPage=20
name | type | default |
---|---|---|
page | int | 1 |
perPage | int | 15 |
as per laravel pagination
{
"total": 53,
"per_page": "1",
"current_page": 1,
"last_page": 53,
"next_page_url": "http:\/\/exemple.com\/api\/v1\/users?page=2",
"prev_page_url": null,
"from": 1,
"to": 1,
"data": [{
...
}]
}
http://exemple.com/api/v1/users?in=1;2;3;4;5;6
name | type | format |
---|---|---|
in | ids | string with delimiter or array of int |
The notIn
array has precedence over the in
array
http://exemple.com/api/v1/users?in=1;2;3;4;5;6¬In=2
[
{ "name": "user1", "id": 1 },
{ "name": "user3", "id": 3 },
...
]
name | field | format |
---|---|---|
in | id | string with delimiter or array of int |
notIn | id | string with delimiter or array of int |
http://exemple.com/api/v1/users?offset=10
http://exemple.com/api/v1/users?limit=20
http://exemple.com/api/v1/users?offset=10&limit=20
name | field | format | default |
---|---|---|---|
offset | id | int | 1 |
limit | id | int | 15 |
If you find a bug or want to report somethings just drop an issue.
Contributions are very welcome. Just fork it and do a PR.