rest-controllers.md 6.65 KB
Newer Older
Qiang Xue committed
1 2 3
Controllers
===========

Qiang Xue committed
4 5
After creating the resource classes and specifying how resource data should be formatted, the next thing
to do is to create controller actions to expose the resources to end users through RESTful APIs.
Qiang Xue committed
6 7 8

Yii provides two base controller classes to simplify your work of creating RESTful actions:
[[yii\rest\Controller]] and [[yii\rest\ActiveController]]. The difference between these two controllers
Qiang Xue committed
9 10 11 12
is that the latter provides a default set of actions that are specifically designed to deal with
resources represented as [Active Record](db-active-record.md). So if you are using [Active Record](db-active-record.md)
and are comfortable with the provided built-in actions, you may consider extending your controller classes
from [[yii\rest\ActiveController]], which will allow you to create powerful RESTful APIs with minimal code.
Qiang Xue committed
13

Qiang Xue committed
14 15
Both [[yii\rest\Controller]] and [[yii\rest\ActiveController]] provide the following features, some of which
will be described in detail in the next few sections:
Qiang Xue committed
16 17

* HTTP method validation;
Qiang Xue committed
18 19 20
* [Content negotiation and Data formatting](rest-response-formatting.md);
* [Authentication](rest-authentication.md);
* [Rate limiting](rest-rate-limiting.md).
Qiang Xue committed
21

Qiang Xue committed
22
[[yii\rest\ActiveController]] in addition provides the following features:
Qiang Xue committed
23

Qiang Xue committed
24 25 26 27
* A set of commonly needed actions: `index`, `view`, `create`, `update`, `delete`, `options`;
* User authorization in regarding to the requested action and resource.


Qiang Xue committed
28
## Creating Controller Classes <a name="creating-controller"></a>
Qiang Xue committed
29 30 31 32 33 34 35 36 37 38 39 40

When creating a new controller class, a convention in naming the controller class is to use
the type name of the resource and use singular form. For example, to serve user information,
the controller may be named as `UserController`.

Creating a new action is similar to creating an action for a Web application. The only difference
is that instead of rendering the result using a view by calling the `render()` method, for RESTful actions
you directly return the data. The [[yii\rest\Controller::serializer|serializer]] and the
[[yii\web\Response|response object]] will handle the conversion from the original data to the requested
format. For example,

```php
Qiang Xue committed
41
public function actionView($id)
Qiang Xue committed
42
{
Qiang Xue committed
43
    return User::findOne($id);
Qiang Xue committed
44 45 46
}
```

Qiang Xue committed
47

Qiang Xue committed
48
## Filters <a name="filters"></a>
Qiang Xue committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

Most RESTful API features provided by [[yii\rest\Controller]] are implemented in terms of [filters](runtime-filtering.md).
In particular, the following filters will be executed in the order they are listed:

* [[yii\filters\ContentNegotiator|contentNegotiator]]: supports content negotiation, to be explained in
  the [Response Formatting](rest-response-formatting.md) section;
* [[yii\filters\VerbFilter|verbFilter]]: supports HTTP method validation;
* [[yii\filters\AuthMethod|authenticator]]: supports user authentication, to be explained in
  the [Authentication](rest-authentication.md) section;
* [[yii\filters\RateLimiter|rateLimiter]]: supports rate limiting, to be explained in
  the [Rate Limiting](rest-rate-limiting.md) section.

These named filters are declared in the [[yii\rest\Controller::behaviors()|behaviors()]] method.
You may override this method to configure individual filters,  disable some of them, or add your own filters.
For example, if you only want to use HTTP basic authentication, you may write the following code:

```php
use yii\filters\auth\HttpBasicAuth;

public function behaviors()
{
    $behaviors = parent::behaviors();
    $behaviors['authenticator'] = [
        'class' => HttpBasicAuth::className(),
    ];
    return $behaviors;
}
```

Qiang Xue committed
78 79

## Extending `ActiveController` <a name="extending-active-controller"></a>
Qiang Xue committed
80

Qiang Xue committed
81 82
If your controller class extends from [[yii\rest\ActiveController]], you should set
its [[yii\rest\ActiveController::modelClass||modelClass]] property to be the name of the resource class
Qiang Xue committed
83 84 85
that you plan to serve through this controller. The class must extend from [[yii\db\ActiveRecord]].


Qiang Xue committed
86
### Customizing Actions <a name="customizing-actions"></a>
Qiang Xue committed
87 88 89 90 91 92 93 94 95

By default, [[yii\rest\ActiveController]] provides the following actions:

* [[yii\rest\IndexAction|index]]: list resources page by page;
* [[yii\rest\ViewAction|view]]: return the details of a specified resource;
* [[yii\rest\CreateAction|create]]: create a new resource;
* [[yii\rest\UpdateAction|update]]: update an existing resource;
* [[yii\rest\DeleteAction|delete]]: delete the specified resource;
* [[yii\rest\OptionsAction|options]]: return the supported HTTP methods.
Qiang Xue committed
96

Qiang Xue committed
97 98
All these actions are declared through the [[yii\rest\ActiveController::actions()|actions()]] method.
You may configure these actions or disable some of them by overriding the `actions()` method, like shown the following,
Qiang Xue committed
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

```php
public function actions()
{
    $actions = parent::actions();

    // disable the "delete" and "create" actions
    unset($actions['delete'], $actions['create']);

    // customize the data provider preparation with the "prepareDataProvider()" method
    $actions['index']['prepareDataProvider'] = [$this, 'prepareDataProvider'];

    return $actions;
}

public function prepareDataProvider()
{
    // prepare and return a data provider for the "index" action
}
```

Qiang Xue committed
120
Please refer to the class references for individual action classes to learn what configuration options are available.
Qiang Xue committed
121 122


Qiang Xue committed
123
### Performing Access Check <a name="performing-access-check"></a>
Qiang Xue committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152

When exposing resources through RESTful APIs, you often need to check if the current user has the permission
to access and manipulate the requested resource(s). With [[yii\rest\ActiveController]], this can be done
by overriding the [[yii\rest\ActiveController::checkAccess()|checkAccess()]] method like the following,

```php
/**
 * Checks the privilege of the current user.
 *
 * This method should be overridden to check whether the current user has the privilege
 * to run the specified action against the specified data model.
 * If the user does not have access, a [[ForbiddenHttpException]] should be thrown.
 *
 * @param string $action the ID of the action to be executed
 * @param \yii\base\Model $model the model to be accessed. If null, it means no specific model is being accessed.
 * @param array $params additional parameters
 * @throws ForbiddenHttpException if the user does not have access
 */
public function checkAccess($action, $model = null, $params = [])
{
    // check if the user can access $action and $model
    // throw ForbiddenHttpException if access should be denied
}
```

The `checkAccess()` method will be called by the default actions of [[yii\rest\ActiveController]]. If you create
new actions and also want to perform access check, you should call this method explicitly in the new actions.

> Tip: You may implement `checkAccess()` by using the [Role-Based Access Control (RBAC) component](security-authorization.md).