1. Please refer to the previous blog post first: https://www.shuijingwanwq.com/2016/11/26/1436/
2. Prepare to implement a RESTful Web service based on shujujiexi
3. Generate a model using Gii in the frontend application. Edit \environments\dev\frontend\config\main-local.php, as shown in Figure 1
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
'allowedIPs' => ['127.0.0.1', '::1'],
];

4. Run .\init in Windows PowerShell to overwrite \frontend\config\main-local.php and set the IPs allowed to access Gii, as shown in Figure 2

5. Open the URL: http://www.kaiqiu_shujujiexi_api.dev/index.php?r=gii. You can now access Gii, as shown in Figure 3

6. Edit \frontend\config\main.php to enable pretty URLs, as shown in Figure 4
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],

7. Open the URL: http://www.kaiqiu_shujujiexi_api.dev/gii, as shown in Figure 5

8. Create the corresponding model based on the database table kq_schedule, as shown in Figure 6

9. Click the Start button under Model Generator to generate the Schedule model with the namespace common\models, so that other applications can use this model later. Internationalization support is not needed at this point, as shown in Figure 7

10. Click the Generate button to generate the model file \common\models\Schedule.php, as shown in Figure 8

11. Create a controller \shujujiexi\controllers\ScheduleController.php, as shown in Figure 9

<?php
namespace shujujiexi\controllers;
use yii\rest\ActiveController;
class ScheduleController extends ActiveController
{
public $modelClass = 'common\models\Schedule';
}12. Configure the URL rules by modifying the configuration of the urlManager component, as shown in Figure 10

'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'schedule',
],
],
],
13. In Postman, send a GET request to: shujujiexi.kaiqiu_shujujiexi_api.dev/schedules. The response is correct, as shown in Figure 11

14. To implement its own business logic within the shujujiexi application, it is recommended to create a new \shujujiexi\models\Schedule.php that extends \common\models\Schedule, as shown in Figure 12

15. Edit the controller \shujujiexi\controllers\ScheduleController.php to re-specify the model as shujujiexi\models\Schedule, as shown in Figure 13

16. In Postman, send a GET request to: shujujiexi.kaiqiu_shujujiexi_api.dev/schedules. The response is correct, as shown in Figure 11

17. In Postman, send a PUT request to: shujujiexi.kaiqiu_shujujiexi_api.dev/schedules/1. The response is correct, as shown in Figure 14

18. Configure the only and except options to explicitly list which actions are supported and which are disabled. For example, to only support GET list, modify the configuration of the urlManager component, as shown in Figure 15

'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'schedule',
'only' => ['index'],
],
],
],
19. In Postman, send a PUT request to: shujujiexi.kaiqiu_shujujiexi_api.dev/schedules/1. It returns a 404 response, as shown in Figure 16

20. Based on the URL rule: ‘GET,HEAD users’ => ‘user/index’, in Postman, send a HEAD request to: shujujiexi.kaiqiu_shujujiexi_api.dev/schedules. The response is empty and can be ignored; all other requests return 404, as shown in Figure 17

21. To resolve the issue where the 404 response format is HTML, edit \shujujiexi\config\main.php to set the default response format to JSON, as shown in Figure 18

'response' => [
'format' => yii\web\Response::FORMAT_JSON,
],
22. Execute step 19 again. The 404 response is now in JSON format, as shown in Figure 19

23. Implement data serialization to include pagination information in the response body to simplify client development. Edit \shujujiexi\controllers\ScheduleController.php, as shown in Figure 20

public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items',
];
24. In Postman, send a GET request to: shujujiexi.kaiqiu_shujujiexi_api.dev/schedules. The response is correct and includes pagination information in the response body, as shown in Figure 21

25. RESTful APIs are typically stateless. Therefore, configure the user application component by editing \shujujiexi\config\main.php, as shown in Figure 22

'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => false,
'identityCookie' => ['name' => '_identity-shujujiexi', 'httpOnly' => true],
'enableSession' => false,
'loginUrl' => null,
],
26. Implement versioning by creating a new directory \shujujiexi\modules. Its structure is shown in Figure 23

27. The contents of \shujujiexi\modules\v1\Module.php are shown in Figure 24

28. The contents of \shujujiexi\modules\v1\controllers\ScheduleController.php are shown in Figure 25

29. The contents of \shujujiexi\modules\v1\models\Schedule.php are shown in Figure 26

30. Configure the URL rules by modifying the configuration of the urlManager component, as shown in Figure 27

31. Configure the module rules, as shown in Figure 28

'modules' => [
'v1' => [
'basePath' => '@app/modules/v1',
'class' => 'shujujiexi\modules\v1\Module'
],
],
31. In Postman, send a GET request to: shujujiexi.kaiqiu_shujujiexi_api.dev/schedules. It returns a 404 response as expected, as shown in Figure 29

32. In Postman, send a GET request to: shujujiexi.kaiqiu_shujujiexi_api.dev/v1/schedules. The response is correct, as shown in Figure 30

33. Adjust the structure of the response data. The default fields are code, message, and data
34. Copy \vendor\yiisoft\yii2\rest\Serializer.php to \shujujiexi\rests\Serializer.php. Its contents extend \yii\rest\Serializer and only retain serializeDataProvider(), as shown in Figure 31

<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace shujujiexi\rests;
use Yii;
/**
* Serializer converts resource objects and collections into array representation.
*
* Serializer is mainly used by REST controllers to convert different objects into array representation
* so that they can be further turned into different formats, such as JSON, XML, by response formatters.
*
* The default implementation handles resources as [[Model]] objects and collections as objects
* implementing [[DataProviderInterface]]. You may override [[serialize()]] to handle more types.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Serializer extends \yii\rest\Serializer
{
/**
* Serializes a data provider.
* @param DataProviderInterface $dataProvider
* @return array the array representation of the data provider.
*/
protected function serializeDataProvider($dataProvider)
{
if ($this->preserveKeys) {
$models = $dataProvider->getModels();
} else {
$models = array_values($dataProvider->getModels());
}
$models = $this->serializeModels($models);
if (($pagination = $dataProvider->getPagination()) !== false) {
$this->addPaginationHeaders($pagination);
}
if ($this->request->getIsHead()) {
return null;
} elseif ($this->collectionEnvelope === null) {
return $models;
} else {
$result = [
$this->collectionEnvelope => $models,
];
if ($pagination !== false) {
return ['code' => '00000', 'message' => 'success', 'data' => array_merge($result, $this->serializePagination($pagination))];
// return array_merge($result, $this->serializePagination($pagination));
} else {
return ['code' => '00000', 'message' => 'success', 'data' => $result];
// return $result;
}
}
}
}
35. Edit the controller \shujujiexi\controllers\ScheduleController.php, as shown in Figure 32

36. In Postman, send a GET request to: shujujiexi.kaiqiu_shujujiexi_api.dev/v1/schedules. The response is correct, as shown in Figure 33

37. To freely define the implementation flow for this request’s response, analyzing \vendor\yiisoft\yii2\rest\ActiveController.php reveals that the default implementation class for the Index action is yii\rest\IndexAction, as shown in Figure 34

38. Copy \vendor\yiisoft\yii2\rest\IndexAction.php to \shujujiexi\rests\schedule\IndexAction.php, as shown in Figure 35

39. Edit the controller \shujujiexi\controllers\ScheduleController.php, as shown in Figure 36

public function actions()
{
$actions = parent::actions();
$actions['index']['class'] = 'shujujiexi\rests\schedule\IndexAction';
return $actions;
}
40. Edit \shujujiexi\rests\schedule\IndexAction.php, as shown in Figure 37

<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace shujujiexi\rests\schedule;
use Yii;
use yii\rest;
use yii\data\ActiveDataProvider;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class IndexAction extends rest\IndexAction
{
/**
* @var callable a PHP callable that will be called to prepare a data provider that
* should return a collection of the models. If not set, [[prepareDataProvider()]] will be used instead.
* The signature of the callable should be:
*
* ```php
* function ($action) {
* // $action is the action object currently running
* }
* ```
*
* The callable should return an instance of [[ActiveDataProvider]].
*/
/**
* Prepares the data provider that should return the requested collection of the models.
* @return ActiveDataProvider
*/
protected function prepareDataProvider()
{
if ($this->prepareDataProvider !== null) {
return call_user_func($this->prepareDataProvider, $this);
}
/* @var $modelClass \yii\db\BaseActiveRecord */
$modelClass = $this->modelClass;
return new ActiveDataProvider([
'query' => $modelClass::find()->where(['status' => 1]),
]);
}
}
41. In Postman, send a GET request to: shujujiexi.kaiqiu_shujujiexi_api.dev/v1/schedules. The response is correct and only returns data where status is 1, as shown in Figure 38

Notes:
1. The model file generated by Gii is stored in the common directory;
2. For v1, it is recommended to implement the methods in the controllers and models within \shujujiexi\controllers and \shujujiexi\models;
3. For v2, if different functionality implementations are needed, it is recommended to override the methods in the controllers and models within \shujujiexi\modules\v1\controllers and \shujujiexi\modules\v1\models;
4. The directory structure of shujujiexi\rests is similar to that of shujujiexi\views, where each controller has its corresponding directory;
5. In each major version (within the corresponding module), use the Accept HTTP request header to determine the minor version number and write conditional code to respond to the respective minor version;
// via parameter
Accept: application/json; version=1.0.0
