RESTfulAPI规范

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
	}
}
相关推荐
唐青枫2 小时前
Java JDBC 实战指南:从 Connection 到事务和连接池
java
一个做软件开发的牛马3 小时前
MyBatis-Plus 从零实战:完整搭建可运行 Demo,BaseMapper 零 SQL、Wrapper 条件构造、分页插件与代码生成器详解
java·后端
用户3721574261353 小时前
Java 处理 PDF 图片:提取 PDF 中的图片,并压缩 PDF 图片体积
java
用户3721574261353 小时前
Java 打印 Word 文档:从基础打印到高级设置
java
用户35218024547519 小时前
当 Prompt 学会"热更新":Spring Boot × Nacos3 AI 实战
java·spring boot·ai编程
东坡白菜1 天前
破局全栈:一个前端开发的Java入门实战记录(1)
java·全栈
唐青枫1 天前
Java Tomcat 实战指南:从 Servlet 容器到 Spring Boot 部署
java
wsaaaqqq1 天前
roudan:自由选择实体、灵活操作数据、快速写入数据库的 Java 框架
java
plainGeekDev1 天前
null 判断 → Kotlin 可空类型
android·java·kotlin
糖拌西瓜皮1 天前
Java开发者视角:深入理解Node.js异步编程模型
java·后端·node.js