博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
阿北的知识分享小程序中restful使用经验贴
阅读量:7073 次
发布时间:2019-06-28

本文共 5143 字,大约阅读时间需要 17 分钟。

大家知道我最近在给“阿北的知识分享”微信小程序改版,使用的是yii2中的restful功能,接下来把遇到的一些问题及小技巧分享一下。

先安利一下小程序码

开始分享。

URL要重写

我们知道restful风格的url一般是这样的

  • GET /users
  • POST /users
  • DELETE /users/1

我们yii2默认的url形式是index.php?r=controller/action。

虽然说yii2已经提供了专门针对于restful的路由规则,但是我们还是需要服务器支持url重写把index.php去掉。

我用的是nginx,如下配置

location / {    if (!-e $request_filename){        rewrite ^/(.*) /index.php last;    }}

如果你的是apache可以如下配置

// Apache需要支持url重写其AllowOverride为allAllowOverride:all//web目录下增加.htaccess,隐藏index.php文件 内容如下RewriteEngine onRewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteRule . index.php

RewriteEngine OnRewriteBase /RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteRule ^(.*)\?*$ index.php/$1 [L,QSA]

不要DELETE了

默认情况下yii2的restful已经提供了index、view、update、create和delete共5个action来满足于对资源的不同行为。可能你的接口中不需要delete,有两个方法

url规则中配置(推荐)

比如我不希望开放 DELETE /users/1 则可以配置对应的url规则如下

[    'class' => 'yii\rest\UrlRule',    'controller' => 'user',    'except'=>['delete']],

重写action

我们知道这些内置方法使用了actions方法实现,我们可以复写这个函数。

class UserController extends ActiveController {    public $modelClass = 'app\models\User';    public function actions() {        $actions = parent::actions();        unset($actions['delete']);        return $actions;    }    ...}

两种方法都可以实现但是返回结果不相同,感兴趣的同学可以自己体验下。

加个action叫abc

内置方法满足了很多,需求太复杂我想自己在控制器里增加一个actionAbc的方法,如何配置那?看下面的代码,还是在urlManager里搞定。

[    'class' => 'yii\rest\UrlRule',    'controller' => 'user',    'except'=>['delete','update','index'],    'extraPatterns'=>[        'POST abc'=>'abc',    ]],

这样你就可以通过 POST /users/abc 来调用User控制器的abc Action了。

我要更多数据

我想通过 GET /users 获取会员的id和nickname字段,很简单在get参数中传入fields='id,nickname',这很容易毕竟id和nickname就是user表的列,但是我还想获得每个会员下的订单数,而订单数并不属于user表,方法如下

增加get参数

我们需要增加一个叫做expand的参数,值为你要获取的字段名字,逗号分隔每一个。

GET /users?fields='id,nickname'&expand='oTotal'

配置user模型

我们需要重写一个叫做extraFields的方法

public function extraFields() {    return [        'oTotal'    ];}

编写具体逻辑

接下来我们要在User模型中编写实现oTotal的函数

public function getOTotal(){    return Order::find()->where(['user_id'=>$this->id])->count();}

你发现了什么?你是否记起了在yii2中一个叫做关联的概念,你是否发现获取多种数据变得很简单了?

json怎么病了

使用小程序发起服务器请求,比如新建一本书,我们一般喜欢编写如下代码

wx.request({    method: 'POST',    data: {        name: name    },    url: app.globalData.remoteUrl + '/books',    header: {        'content-type': 'application/json'    },    success: function (res) {            }})

这里我设置了'content-type': 'application/json',问题发生了,我在服务器端无法获取json中的name值。

很简单,默认情况下yii2的restful并不支持对请求中json的数据解析,还好小小配置下就可以了。

// config/web.php'components' => [    'request' => [        'cookieValidationKey' => '',        'parsers' => [            'application/json' => 'yii\web\JsonParser',        ]    ],]

增加一个JsonParser解析器就可以了。

认证问题

网页上有登录,但是restful上没有session,没关系我们可以使用access token来搞定,配置很简单。

比如我现在要求GET /users 必须是登陆后访问。

配置user模型和表

首先为user表配置一个access_token字段,同时在User模型下做一个generateAccessToken方法

public function generateAccessToken(){    $this->access_token = Yii::$app->security->generateRandomString();}

该方法主要用于生成access_token值。

当然我们的User模型需要实现 yiiwebIdentityInterface 接口,否则使用Yii::$app->user无法访问的,关于IdentityInterface我想在yii2登录这里已经很熟悉了,记住restful的认证如果生效还要实现如下方法

public static function findIdentityByAccessToken($token, $type = null){    $model = User::find()->where(['access_token'=>$token])->one();    return $model;}

到这里User模型就配置好了,小提醒:如果你想做一些登录那一刻的事儿,可以也放到findIdentityByAccessToken,比如记录登录时间啥的。

配置action

接下来我们来对具体的接口进行认证限制,复写behaviors行为,如下

use yii\filters\auth\HttpBearerAuth;class UserController extends ActiveController {    public $modelClass = "app\models\User";    public function behaviors() {        $behaviors = parent::behaviors();        $behaviors['contentNegotiator']['formats'] = ['application/json'=>Response::FORMAT_JSON];        $behaviors['authenticator'] = [            'class'=>HttpBearerAuth::className(),            'only'=>[                'index'            ],        ];        return $behaviors;    }}

这样就搞定了,我们这里用的是HttpBearerAuth认证,就是在请求的header里面写Authorization,yii2的restful还支持其他的。记住这个认证过程是自动的,并且我们在认证的方法里可以使用Yii::$app->user->id获取当前会员的ID。

列表更多参数

我们知道通过 GET /users 可以获得会员列表,但是你可能说我要获取来自于微信平台的会员(user表里有一个字段plat代表来源平台),怎么办?

我们需要重新编写该接口并接受plat参数,在User控制器中先设置新的prepareDataProvider函数,它用来接收参数并生成会员列表数据,返回的是一个ActiveDataProvider结果集。

namespace app\modules\xcx\controllers;use Yii;use yii\rest\ActiveController;....class UserController extends ActiveController {    public $modelClass = 'app\models\User';    public function actions() {        $actions = parent::actions();        $actions['index']['prepareDataProvider'] = [$this,'prepareDataProvider'];        return $actions;    }    public function prepareDataProvider(){        $params = Yii::$app->request->queryParams;        $modelClass = $this->modelClass;        $query = $modelClass::find()->where(['plat'=>$params['plat']]);        $provider = new ActiveDataProvider([            'query'=>$query->orderBy(['created_at'=>SORT_DESC])        ]);        return $provider;    }}

首先通过 $actions['index']['prepareDataProvider'] = [$this,'prepareDataProvider'] 告诉yii2我要自定义获取结果集的方法,接下来定义这个方法,在prepareDataProvider里可以通过Yii::$app->request->queryParams 接收过来的get参数的值。

小结

以上就是目前为止在使用yii2的restful开发小程序时候使用的一些知识和技巧,希望对你有用,以后如果有再分享哈。

转载地址:http://ahkml.baihongyu.com/

你可能感兴趣的文章
python之通过“反射”实现不同的url指向不同函数进行处理(反射应用一)
查看>>
10.6 监控io性能;10.7 free;10.8 ps;10.9 查看网络状态;10.10 抓包
查看>>
delegate的用法
查看>>
Ubuntu <2TB sdb preseed示例
查看>>
Android开发之旅:组件生命周期(二)
查看>>
使用LVS+NAT搭建集群实现负载均衡
查看>>
LVM 磁盘分区扩容
查看>>
mysql5.6之key_buffer_size优化设置
查看>>
查看Linux服务器网卡流量小脚本shell和Python各一例
查看>>
Linux TC的ifb原理以及ingress流控
查看>>
AgileEAS.NET之敏捷并行开发方法
查看>>
Java源码分析系列之ArrayList读后感
查看>>
性能测试之手机号码python生成方式
查看>>
统计数据库大小的方法
查看>>
PHP递归遍历文件夹
查看>>
用户系列之五:用户SID查看之终结版
查看>>
ubuntu 11.10下载和编译Android源码
查看>>
千兆级LTE的一小步,5G之路的一大步
查看>>
跟我一起写 Makefile(一)
查看>>
管理日志-原创理论工具--技能方格图
查看>>