restful api url设计规范为(先将此规范记住 后续有详细解释):
/版本/访问控制/域对象
/版本/访问控制/域对象/动作
约束:
域对象 用名词而不是动词
直接使用域对象名 使用/ticket而不是复数/tickets 节省脑力
域对象关系表达 最大不超过2层 /ticket/12/message
正确区分 GET POST PUT DELETE 请求方法
无法用名词+请求方法表述的可以扩展为 /域对象/动词 例如 POST /user/login
restful API 访问控制
用于在网关统一进行访问控制, 访问控制分为
pb - public 所有请求均可访问
pt - protected 需要进行token认证通过后方可访问
df - default 网关进行token认证 并且请求参数和返回结果进行加解密
修改为请求头含有X-Encrypt=v1时,网关对请求结果和返回响应进行v1版本加解密算法( 算法为 base64(aes(body)) ),对请求解密和对响应加密
pv - private 无法通过网关访问 只能微服务内部调用
其他 同pt
restful API 版本以微服务为粒度, 整个微服务进行版本升级
例如一个微服务有如下API
GET /v1/pb/user
POST /v1/pb/user
PUT /v1/pb/user
如果 POST /v1/pb/user 需要升级 则将整个微服务/v1升级到/v2, 同时保证版本兼容的api老版本可以继续访问
html
GET /v2/pb/user //等价于 GET /v1/pb/user
POST /v1/pb/user //标记为已废弃
POST /v2/pb/user
PUT /v2/pb/user //等价于 PUT /v1/pb/user
代码实现(方法上添加注解):
GET方式{version}可以是任意值,v1,v2均可
java
@ApiImplicitParam(name = "version", paramType = "path", allowableValues = DemoAutoConfig.COMPATIBLE_VERSION, required = true)
@GetMapping("/{version}/pb/user")
POST v1 标记为已废弃,但是仍可使用
java
@Deprecated
@PostMapping("/v1/pb/user")POST{version}
应是当前版本,只能是v2
java
@ApiImplicitParam(name = "version", paramType = "path", allowableValues = DemoAutoConfig.CURRENT_VERSION, required = true)
@PostMapping("/{version}/pb/user")
要求兼容上一个版本 如果当前是 /v3 则 /v2 要求可以正常使用 /v1 不做要求
如果无法兼容 需要通知所有服务消费者 并约定版本火车 一起上线时间
正确使用HTTP返回状态
目前常用http状态码:
200 正常 直接返回所需数据
javascript
{
id: 1234567890, // 分布式ID注意不要超过JavaScript精度
name: '',
date: '2022-04-24 14:38:21'//
}
400 请求无效 请求参数不合法 业务异常 等 返回response封装对象n
javascript
{
code: '', // 业务编码 以便前端根据具体编码进行不同操作 例如转账失败:包括 余额不足 自己账户被冻结 对方账户被冻结等业务情况
msg: '', // 提示消息 提示给用户
error: '', // 错误消息 开发测试环境才会用到 异常堆栈信息 方便快速定位问题 生产环境关闭
data: {} // 额外信息 前后端共同约定
}
401 未认证 未登陆
403 无权限 已登陆
500 服务器上述状态码无法描述的其他问题
非200状态码均返回response封装对象
分页 过滤 排序
查询尽量使用GET方式方便使用 如果特别复杂查询可以使用POST /search
请求示例: POST /{version}/pb/demos/search 参见PageRequestPageData 对象
javascript
{
"filter": { //
"name": "string",
"phone": "string",
"updateUserId": "string"
},
"group": "", //
"sort": "", // -desc
"filed": "", //
"pageNumber": 1, // 1
"pageSize": 10, //
"total": 0 // 00
}
返回值:
javascript
{
"entities": [ //
{
"gmtCreate": "2018-10-09T03:21:37.232Z",
"gmtUpdate": "2018-10-09T03:21:37.232Z",
"id": 0,
"name": "string",
"phone": "string",
"updateUserId": "string"
}
],
"next": { // APPnext
"filed": "",
"filter": {
"name": "string",
"phone": "string",
"updateUserId": "string"
},
"group": "",
"pageNumber": 1,
"pageSize": 10,
"sort": "",
"total": 0
}
}