今天,写篇文章介绍一下 RESTful API 中的动词覆盖吧。
在开发各种小程序的时候,总是会遇到不能正常支持 HTTP 请求的平台,比如支付宝小程序只支持 GET 和 POST 请求,这时候充分利用 HTTP 请求方法的 RESTful API 就会遇到问题,不支持 PUT, PATCH, DELETE 请求,该怎么办呢?嗯,使用动词覆盖。
什么是动词覆盖
我最初遇到不支持全部 HTTP 请求的时候,解决方案是修改 API 路径,比如 DELETE /user/:id 时,我的方案是 POST /user/:id/delete。后来看了阮一峰的《RESTful API 最佳实践实践 》,才明白有动词覆盖这回事儿,感觉动词覆盖确实更优雅,手动狗头。。。
有些客户端只能使用GET和POST这两种方法。服务器必须接受POST模拟其他三个方法(PUT、PATCH、DELETE)。
这时,客户端发出的 HTTP 请求,要加上X-HTTP-Method-Override属性,告诉服务器应该使用哪一个动词,覆盖POST方法。
POST /api/Person/4 HTTP/1.1
X-HTTP-Method-Override: PUT
上面代码中,X-HTTP-Method-Override指定本次请求的方法是PUT,而不是POST。
前端
前端的工作就是在请求的 header 中添加字段 X-HTTP-Method-Override,举个例子,比如我使用了 uniapp 的插件 luchAPI,在请求的时候我设置了请求的 option。
var url = "/user/"+that.$store.state.userInfo.id;
that.$http.post(url, req, {header:{'X-HTTP-Method-Override':"put"}})
.then(res=>{
console.log("res:", res);
if(res.statusCode == 200){
console.log("update prfile: ", res);
that.$store.commit("setUserInfo", res.data);
uni.showToast({
title:"修改成功",
icon:"none"
})
}else{
uni.showToast({
title:res.error,
icon:"none"
})
}
});
后端
后端使用的是 ThinkPHP 框架,本来准备自己实现请求覆盖的,虽然 ThinkPHP 官方的文档中没找到,但是看了下源码,居然体贴实现了这个功能,下面是 ThinkPHP 框架的源码。ThinkPHP 5.0.24 中 \thinkphp\library\think\Request.php
/**
* 当前的请求类型
* @access public
* @param bool $method true 获取原始请求类型
* @return string
*/
public function method($method = false)
{
if (true === $method) {
// 获取原始请求类型
return $this->server('REQUEST_METHOD') ?: 'GET';
} elseif (!$this->method) {
if (isset($_POST[Config::get('var_method')])) {
$method = strtoupper($_POST[Config::get('var_method')]);
if (in_array($method, ['GET', 'POST', 'DELETE', 'PUT', 'PATCH'])) {
$this->method = $method;
$this->{$this->method}($_POST);
} else {
$this->method = 'POST';
}
unset($_POST[Config::get('var_method')]);
} elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
$this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
} else {
$this->method = $this->server('REQUEST_METHOD') ?: 'GET';
}
}
return $this->method;
}
Koa.js 可以使用 https://github.com/koa-modules/methodoverride
来源:https://javascript.net.cn/articles/686