lovelilili 发表于 2020-10-14 21:19

从零开始搭建完整的全栈系统(三)——restfulApi的编写


接上两篇:
从零开始搭建完整的全栈系统(一)——数据库设计及爬虫编写

从零开始搭建完整的全栈系统(二)——简单的WEB展示网站的搭建

本篇避免踩雷被删。

## 创建API应用入口:

1,复制 backend ⾄ api, environments/dev/backend ⾄ environments/dev/
api 以及 environments/prod/backend ⾄ environments/prod/api.
2,修改配置⽂件main.php,需要修改应⽤id、命名空间、⽤户组件和url美化
的配置内容

```php
'id' => 'app-api',
'controllerNamespace' => 'api\controllers',
```
3,在 common\config\bootstrap.php 中添加api的路径别名

```php
Yii::setAlias('@api', dirname(dirname(__DIR__)) . '/api');
```
单独创建api入口的好处:
单独创建API应⽤,⽬的是便于维护。可以避免这些问题:
• 配置的冲突
• 控制器的命名不便
• url美化规则冲突

## 创建第⼀个API应⽤:

1,创建了vod-detail控制器:
VodDetailController.php

```php
<?php

namespace api\controllers;

use Yii;
use common\models\VodDetail;
use common\models\VodDetailSearch;
use yii\rest\ActiveController;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;

/**
* VodDetailController implements the CRUD actions for VodDetail model.
*/
class VodDetailController extends ActiveController
{
    public $modelClass = 'common\models\VodDetail';
}

```

2,在配置⽂件中,创建了针对vod-detail控制
器的url美化规则:
main.php:

```php
'urlManager' => [
            'enablePrettyUrl' => true,
            //严格解析 至少要符合rules中的一条,否则抛出异常
            'enableStrictParsing' => true,
            'showScriptName' => false,
            'rules' => [
                [
                  'class' => 'yii\rest\UrlRule',
                  'controller' => 'vod-detail',
                ],
            ],
      ],
```

3,配置main-local⽂件,让API应⽤能接收
JSON 格式的输⼊数据:
main-local.php:

```php
'parsers' => [
                'application/json' => 'yii\web\JsonParser',
            ]
```
使用postman调试:

![在这里插入图片描述](https://img-blog.csdnimg.cn/2020090917004622.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDA3NTk1Mg==,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200909170330264.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDA3NTk1Mg==,size_16,color_FFFFFF,t_70#pic_center)


可以看出经过简单的代码编写和配置,完全可以访问输出符合restful风格的Api接口了。
但,还是有些问题要解决。比如:vod_create_time和vod_update_time字段是时间戳,我们需要转换,另外,并没有输出播放地址列表.

时间戳我们不转换,调用时可以在客户端转换,接下来我们实现自定义播放地址字段。

## 字段的⾃定义设置 :

> 可以重写模型类的 fields() 或extraFields()
> ⽅法,根据需求设置字段以及字段的值,这样,Serializer转换出 来的数组就是我们需要的数据了。
>
> 1,在客户端发送的api请求地址上,通过fields参数来指定需要的字段 ,
> 2,我们重写fields⽅法来指定需要的字段,还可以⾃定义字段名。
>,3,在fields⽅法中,通过匿名函数⾃定义字段的值。 ,
>4,通过重写extrafields这个⽅法来⾃定义字段 ,
>5,可以⽤unset来屏蔽字段
我们通过重写extrafields这个⽅法来⾃定义字段 ,实现播放地址。

1,在VodDetail模型类中增加getPlayurls方法,重写extrafields方法:

```php
/***
   * @Return \yii\db\ActiveQuery
   * 获取视频对应的播放地址
   */
    public function getPlayurls()
    {
      return $this->hasMany(PlayUrl::className(), ['url_id' => 'url_id']);
//      $playurls = $this->hasMany(PlayUrl::className(), ['url_id' => 'url_id']);
//      return ArrayHelper::index($playurls, null, 'play_from');
    }



    /**
   * 重写extraFields 添加关联字段
   * @return array|false
   */

    public function extraFields()
    {
      return ['playurls'];
    }
```
2,配置Url美化规则默认显示自定义的extraFields字段'playurls':

```php
'ruleConfig' => [
                        'class' => 'yii\web\UrlRule',
                        'defaults' => [
                            'expand' => 'playurls',
                        ],
                  ],
```

再次通过postman模拟请求api可以看到播放地址已经显示了:
![显示播放地址](https://img-blog.csdnimg.cn/20200909174023837.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDA3NTk1Mg==,size_16,color_FFFFFF,t_70#pic_center)

## 在控制器中实现类似WEB网站中列表页的按任何字段搜索和排序功能:

VodDetailController.php
先释放掉默认的index方法:
```php
public function actions()
    {
      $actions = parent::actions();
      unset($actions['index']);
      return $actions;
    }
```
再重写index方法:

```php
public function actionIndex()
    {
      $params = Yii::$app->getRequest()->queryParams;
      $searchModel = new VodDetailSearch();
      return $searchModel->search($params);
    }
```

这里就实现了理论上可以按照vod_detail表中的任何字段搜索过滤和排序。

比如按分类过滤:
![按分类过滤](https://img-blog.csdnimg.cn/20200909214620901.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDA3NTk1Mg==,size_16,color_FFFFFF,t_70#pic_center)

按标题搜索:
![按标题搜索](https://img-blog.csdnimg.cn/20200909214648774.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDA3NTk1Mg==,size_16,color_FFFFFF,t_70#pic_center)
按id顺序、倒序排序:
!(https://img-blog.csdnimg.cn/20200909214924784.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDA3NTk1Mg==,size_16,color_FFFFFF,t_70#pic_center)
!(https://img-blog.csdnimg.cn/20200909214924793.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDA3NTk1Mg==,size_16,color_FFFFFF,t_70#pic_center)

甚至支持多个字段联合搜索过滤。。。。

最后,由于api控制器默认实现了增删改查及index方法,我们只需要index方法和查,为了安全我们在url美化中禁用增、删、改。

```php
'except' => ['delete', 'create', 'update'],//设置被禁用的http动词
```

很少的代码量并搭配简单的配置,就实现了和web网站一样功能的 符合restful风格的Api。

zsxxdd 发表于 2020-10-14 23:36

好多谢分享
页: [1]
查看完整版本: 从零开始搭建完整的全栈系统(三)——restfulApi的编写