在业余确实比较少,现在又学习了Yii2 RESTful Verbs,学习过程中肯定还是很曲折的,各种问题都会在下面进行阐述。
常用的HTTP动词有下面五个(括号里是对应的SQL命令)。
GET(select):从服务器取出资源(一项或多项)。
POST(create):在服务器新建一个资源。
PUT(update):在服务器更新资源(客户端提供改变后的完整资源)。
PATCH(update):在服务器更新资源(客户端提供改变的属性)。
DELETE(delete):从服务器删除资源。
状态码信息
200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
304 not modified - HTTP缓存有效。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
405 method not allowed - 该http方法不被允许。
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
415 unsupported media type - 请求类型错误。
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
429 too many request - 请求过多。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
这两个放一起写是因为比较相似,没有遇到什么问题。我使用的是OAuth2协议的access token,然后通过 HTTP Bearer Tokens 发送到API 服务器,参考 rest-quick-start、rest-authentication 和 security-authentication 三个教程基本可以完成,先上结果如下图。
POST的结果
上传他们的结果是有意义的,给大家参考我的参数是如何填写的。我就遇到在填写POST数据时的格式错误导致一直失败,搞的整个人都不好了。
以下几个问题,小白需要注意的:
第一个:
//路径为 basic/models/xxx.php
public static function findIdentityByAccessToken($token, $type = null)
{
//这里'token'是你数据库字段名称。
return static::findOne(['token' => $token]);
}
//强烈建议加上对字段的验证,这里简单的验证为非空。
public function rules()
{
return [
[['id','type','token'], 'required'], //里面的字段是在数据库自定义的
];
}
第二个:
添加 parsers
否则不能解析你传入的json
'components' => [
'request' => [
'cookieValidationKey' => 'xxxxx',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
'text/json' => 'yii\web\JsonParser',
],
],
]
修改 config/web.php
中 components
的 identityClass
值并设定相关属性。
'user' => [
'identityClass' => 'app\models\Sensor',
'enableAutoLogin' => false,
'enableSession' => false,
'loginUrl' => null,
],
第三个:
看我上传的POST的图片,一定要有 Content-Type
类型为 application/x-www-form-urlencoded
。否则发送过去的数据会解析不出来。
最后一个:
我要吐槽一下框架的OAuth2协议的access token认证,看如下代码:
//文件路径:basic/vendor/yiisoft/yii2/filters/auth/HttpBearerAuth.php
public function authenticate($user, $request, $response)
{
$authHeader = $request->getHeaders()->get('Authorization');
//这儿有一个坑人的正则。
if ($authHeader !== null && preg_match("/^Bearer\\s+(.*?)$/", $authHeader, $matches)) {
$identity = $user->loginByAccessToken($matches[1], get_class($this));
if ($identity === null) {
$this->handleFailure($response);
}
return $identity;
}
return null;
}
该代码里面有一个坑人的正则,导致你 Headers
中的 Authorization
必须是 Bearer token123456
你仅仅写上你的token值他是匹配不出来的。
PATCH就不说了和PUT类似,都是更新数据,在这里只说PUT和DELETE,先上图。
PUT的结果
上图的意思是把token值为1234567的内容修改为重新提交的值。
DELETE的结果
上图的意思是删除token值为1234567的数据。
下面说说如何配置,教程是这样的。
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'Sensor'],
],
]
然后我在DELTET的URL中写 http://localhaost/sensors/1234567
错误为404,我表示很郁闷。然后我发现又是一个坑爹的正则:
//文件路径:basic/vendor/yiisoft/yii2/rest/UrlRule.php
public $tokens = [
'{id}' => '' ,
];
所以我改成这样:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['sensor',],
'tokens' => [
'{id}' => '' //此处修改
],
],
],
],
一个小建议:
写models下的xxx.php(Sensor.php)时,大家最好覆盖一下db的ActiveRecord中函数tableName和primaryKey,好处自行补脑吧。
以上是我在学习中遇到的问题进行了总结,欢迎其他同学加入讨论,若有疑问可以留言。
参考:
Budi Irawan’s Tech Blog
yii2-rest-demo 这个demo的Verbs都是自己覆盖重写的。
最后,晚安~~