代码规范-restful风格之路

419 阅读4分钟

本人工作很多年了,但是一个项目完全是restful风格的我还没有遇到,可能有一些项目要求实施restful风格,但是在对restful的理解又不到位,导致一个项目倒像又不像是restful风格,看起来很老火

刚好最近在整理代码规范,顺便再来整理下,如何规范restful风格,让接口更优雅

一般情况下,如果完全遵循了restful,基本从接口就可以看出,业务是什么?也可以看出接口是否是幂等的。

请求方式

  • GET 用于查询资源信息,含单条查询和多条数据查询。没有幂等性
  • POST 用于新增资源信息,一般是没有幂等性
  • PUT 用于修改资源信息,一般是修改资源对应的所有属性,有幂等性
  • PATCH 用于修改资源信息,一般是修改资源的部分属性,有幂等性
  • DELETE 用于删除资源信息,含单个删除和多个删除,有幂等性

还有很多,目前列举了一些常用的

何为资源

在上面的请求方式中,谈到了资源,到底什么是资源?

资源一般是和领域堆起来的,一般是一个领域对象就会是一个资源,比如用户领域对象(UserE)对应的资源(UserController)一般@RequestMapping("/users"),需要注意的是资源的名词的复数形式,例子为 users

传统方式操作资源

查询,GET

http://127.0.0.1/item/queryUser?id=1

新增,POST

http://127.0.0.1/item/saveUser

更新,POST

http://127.0.0.1/item/updateUser

删除,GET或POST

http://127.0.0.1/item/deleteUser?id=1

restful方式操作资源

这里使用“用户”的案例进行回顾通过 GET、 POST、 PUT、 PATCH、 DELETE 等方式对服务端的资源进行操作。

【GET】 /users # 查询用户信息列表

【GET】 /users/1001 # 查看某个用户信息

【POST】 /users # 新建用户信息

【PUT】 /users/1001 # 更新用户信息(全部字段)

【PATCH】 /users/1001 # 更新用户信息(部分字段)

【DELETE】 /users/1001 # 删除用户信息

之前的操作查询的时候用了queryUser,新增的时候用了saveUser ,修改的时候用了updateUser

其实完全没有这个必要

使用了get请求,就是查询

使用post请求,就是新增的请求

PUT就是修改

delete就是删除

意图很明显,完全没有必要做描述,这就是为什么有了restful.

API设计风格基本规则

  • 使用名词而不是动词

不要使用:

/getAllUsers /createNewUser /deleteAllUser

  • Get方法和查询参数不应该涉及状态改变

使用PUT, POST 和DELETE 方法 而不是 GET 方法来改变状态,不要使用GET 进行状态改变:

  • 使用复数名词

不要混淆名词单数和复数,为了保持简单,只对所有资源使用复数。

/cars 而不是 /car /users 而不是 /user /products 而不是 /product /settings 而部署 /setting

  • 使用子资源表达关系

如果一个资源与另外一个资源有关系,使用子资源:

GET /cars/711/drivers/ 返回 car 711的所有司机 GET /cars/711/drivers/4 返回 car 711的4号司机

  • 使用Http头声明序列化格式

在客户端和服务端,双方都要知道通讯的格式,格式在HTTP-Header中指定

Content-Type 定义请求格式 Accept 定义系列可接受的响应格式

  • 为集合提供过滤 排序 选择和分页等功能

Filtering过滤:

使用唯一的查询参数进行过滤:

GET /cars?color=red 返回红色的cars GET /cars?seats<=2 返回小于两座位的cars集合

Sorting排序:

允许针对多个字段排序

GET /cars?sort=-manufactorer,+model

这是返回根据生产者降序和模型升序排列的car集合

Field selection

移动端能够显示其中一些字段,它们其实不需要一个资源的所有字段,给API消费者一个选择字段的能力,这会降低网络流量,提高API可用性。

GET /cars?fields=manufacturer,model,id,color

Paging分页

使用 limit 和offset.实现分页,缺省limit=20 和offset=0;

GET /cars?offset=10&limit=5

  • 版本化你的API

使得API版本变得强制性,不要发布无版本的API,使用简单数字,避免小数点如2.5.

一般在Url后面使用?v

/blog/api/v1

  • 使用Http状态码处理错误

如果你的API没有错误处理是很难的,只是返回500和出错堆栈不一定有用

Http状态码提供70个出错,我们只要使用10个左右:

200 – OK – 一切正常 201 – OK – 新的资源已经成功创建 204 – OK – 资源已经成功擅长

304 – Not Modified – 客户端使用缓存数据

400 – Bad Request – 请求无效,需要附加细节解释如 "JSON无效" 401 – Unauthorized – 请求需要用户验证 403 – Forbidden – 服务器已经理解了请求,但是拒绝服务或这种请求的访问是不允许的。 404 – Not found – 没有发现该资源 422 – Unprocessable Entity – 只有服务器不能处理实体时使用,比如图像不能被格式化,或者重要字段丢失。

500 – Internal Server Error – API开发者应该避免这种错误。