First of all you need to have validation rules in your model as usual.
Then it's the controllers job and depending on the chosen implementation I can give you some hints:
If your ProductsController extends yii\rest\ActiveController
Basically the easiest way because almost everything is already prepared for you. You just need to provide the $modelClass there and tweak actions() method a bit.
public function actions()
{
$actions = parent::actions();
$actions['index']['dataFilter'] = [
'class' => \yii\data\ActiveDataFilter::class,
'searchModel' => $this->modelClass,
];
return $actions;
}
Here we are modifying the configuration for IndexAction which is by default responsible for GET /products request handling. The configuration is defined here and we want to just add dataFilter key configured to use ActiveDataFilter which processes filter query on the searched model which is our Product. The other actions are remaining the same.
Now you can use DataProvider filters like this (assuming that property storing the product's name is name):
GET /products?filter[name]=chairs will return list of all Products where name is chairs,
GET /products?filter[name][like]=chairs will return list of all Products where name contains word chairs.
If your ProductsController doesn't extend yii\rest\ActiveController but you are still using DataProvider to get collection
Hopefully your ProductsController extends yii\rest\Controller because it will already benefit from serializer and other utilities but it's not required.
The solution is the same as above but now you have to add it by yourself so make sure your controller's action contains something like this:
$requestParams = \Yii::$app->getRequest()->getBodyParams(); // [1]
if (empty($requestParams)) {
$requestParams = \Yii::$app->getRequest()->getQueryParams(); // [2]
}
$dataFilter = new \yii\data\ActiveDataFilter([
'searchModel' => Product::class // [3]
]);
if ($dataFilter->load($requestParams)) {
$filter = $dataFilter->build(); // [4]
if ($filter === false) { // [5]
return $dataFilter;
}
}
$query = Product::find();
if (!empty($filter)) {
$query->andWhere($filter); // [6]
}
return new \yii\data\ActiveDataProvider([
'query' => $query,
'pagination' => [
'params' => $requestParams,
],
'sort' => [
'params' => $requestParams,
],
]); // [7]
What is going on here (numbers matching the code comments):
- We are gathering request parameters from the body,
- If these are empty we take them from the URL,
- We are preparing ActiveDataFilter as mentioned above with searched model being the
Product,
- ActiveDataFilter object is built using the gathered parameters,
- If the build process returns
false it means there is an error (usually unsuccessful validation) so we return the object to user to see list of errors,
- If the filter is not empty we are applying it to the database query for
Product,
- Finally we are configuring ActiveDataProvider object to return the filtered (and paginated and sorted if applicable) collection.
Now you can use DataProvider filters just as mentioned above.
If your ProductsController doesn't use DataProvider to get collection
You need to create your custom solution.