RESTful API 最佳实践
点击上方“武培轩”,选择“设为星标”
技术文章第一时间送达!
RESTful API 概述
基本概念
REST(Representational State Transfer)直译为表现层状态转移,首次是由 Roy Thomas Fielding 在他 2000 年的博士论文中提出。
REST 是一种描述网络中 client 和 server 之间的资源交互方式。
而 RESTful API 就是完全遵循 REST 方式的一套 API 设计规范,简单来说,通过 API 来描述资源的访问方式:
•通过HTTP URL 描述访问什么资源•通过HTTP METHOD 描述对资源的交互方式•通过HTTP CODE 描述资源的交互结果
幂等性
幂等性(Idempotence)本身是一个数学概念,在 HTTP/1.1 规范中幂等性是指
Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.
如果某个方法调用一次或多次产生的副作用是相同的,那么这个方法具有幂等性。
比如在 HTTP 中使用 GET 获取某个资源,无论调用多少次,产生的额外效果都是从服务器获取资源,所以 GET 方式具有幂等性。
而 POST 方法用于在服务器上创建一个资源,由于最终创建的结果每次都是不同的,所以 POST 不具有幂等性。
但是 PUT 方法却是幂等的,因为每次调用产生的效果都是对资源进行更新。
安全方法
安全方法是指不修改资源的 HTTP 方法。譬如,当使用 GET 或者 HEAD 作为资源 URL,都必须不去改变资源的表现形式。
注意:安全方法并不是指服务器上的资源完全不变,而是指资源的表现形式。
比如 GET 方法导致数据上报,关联的一些数据记录等,他实际上是改变了服务器上的某些附加资源的,但是这并不会改变资源的表现形式。
HTTP 方法特性概览
RESTful API设计规则
HTTP URL
HTTP URL 只用于描述访问的资源,而不应该包含对资源的交互方式。HTTP URL 的最佳实践:
•将API部署在专用的域名上,如 api.example.com
•不使用任何大写字符•不使用下划线 _
,可使用中划线 -
代替来分割单词•参数列表要进行 URL 编码•不应该出现描述资源交互方式的动词,应尽量使用描述资源的名词•URI 中的名词表示资源集合,应该使用复数形式•应该避免资源层级太深,可以适当使用参数减少层级•使用斜杆 /
表示资源之间的层级关系•在URI的末尾避免使用 /
•避免在 URI 中使用文件扩展名•如果有必要,需要在 URI 中添加版本号标识
相应的示例如下:
// 下面列出几个错误案例以及改进方法
/userPost // 不应使用大写字母
-> /user-posts
/user/post // 描述资源集合应该用复数
-> /users/posts
/users/addPost // 应避免使用动词
-> POST /users/posts
/users/posts/ // 应移除末尾的 /
-> /users/posts
/users/posts/picture.gif // 应移除文件扩展名 .gif
-> /users/posts/picture
/users/recent_posts // 使用 - 代替 _
-> /users/recent-posts
/users/posts?title=up up // 参数使用 URL 编码
-> /users/posts?name=up%20up
/users/posts/games/picture/today // 应避免资源层级太深
-> /users/posts/picture?type=game&time=today
/users/learning-posts // 应添加版本标识
-> /v1/users/learning-posts
补充说明:
•/users/search 像这个 URI,虽然包含动词 search,但是 search 并没有描述对资源的交互方式,所以这种 URI 也是可以的•/users/posts, /user-posts 这样的两个 URI,第一个描述了层级关系,第二个没有,但是两个 URI 仍然能够很明确的表示资源,并没有谁最好的说法,可以结合所在团队的命名习惯等来选取
HTTP METHOD
严格使用下面的 HTTP 方法来描述资源 CURD 操作方式,应该尽量避免在 POST 方式中删除资源等违背直觉的操作:
•GET: 查询资源•POST: 创建资源•PUT: 更新资源•DELETE: 删除资源
对于一些 GET 中一次性获取大量资源的情况下,比如获取一万个指定资源的情况,可能会出现 HTTP URL 超过长度限制,这个时候可以分批获取。
虽然新版的 HTTP 标准支持在 GET 请求中传送 body,但是一些网络服务器并不能很好的支持,应该慎重使用。
另外对于复杂的资源获取,应该提供通用的资源筛选、排序、分页、字段选择等功能支持,并统一参数规范。例如:
// 过滤:
GET /cars?color=red // 返回红色汽车列表
GET /cars?seats<=2 // 返回最多 2 个座位的汽车列表
// 排序:
GET /cars?sort=-manufactorer,+model
// 字段选择:
GET /cars?fields=manufacturer,model,id,color
// 分页:
GET /cars?offset=10&limit=5
重写 HTTP 方法
一些 HTTP 客户端只支持 GET 和 POST 请求。为了能够加强这些客户端的访问能力,API 需要能够覆盖 HTTP 方法。
尽管这里没有任何强制的标准,但流行的做法是 API 会接收一个请求头 X-HTTP-Method-Override,它的值可以是 PUT、PATCH 或者 DELETE 三者之一。
注意,用来重写 HTTP 方法的 header 只能在 POST 请求中被接受。GET 请求永远不能修改服务器上的数据。
HTTP RESPONSE
关于HTTP请求的返回值,有以下几个最佳实践:
•采用格式化返回数据,推荐 json•充分利用 HTTP 状态码来描述错误类型•规范返回数据的统一格式,以及细分错误类型和提示•应该尽量返回有用的错误信息和提示,唯一的错误码
常用的 HTTP 状态码:
•200 OK – 对成功的 GET、PUT、PATCH 或 DELETE 操作进行响应,也可以被用在不创建新资源的 POST 操作上•201 Created – 对创建新资源的 POST 操作进行响应。应该带着指向新资源地址的 Location header•204 No Content – 对不会返回响应体的成功请求进行响应(比如DELETE请求)•304 Not Modified – HTTP 缓存 header 生效的时候用•400 Bad Request – 请求异常,比如请求中的 body 无法解析•401 Unauthorized – 没有进行认证或者认证非法。当 API 通过浏览器访问的时候,可以用来弹出一个认证对话框•403 Forbidden – 当认证成功,但是认证过的用户没有访问资源的权限•404 Not Found – 当一个不存在的资源被请求•405 Method Not Allowed – 所请求的 HTTP 方法不允许当前认证用户访问•410 Gone – 表示当前请求的资源不再可用。当调用老版本 API 的时候很有用•415 Unsupported Media Type – 如果请求中的内容类型是错误的•422 Unprocessable Entity – 用来表示校验错误•429 Too Many Requests – 由于请求频次达到上限而被拒绝访问
作者:悠悠i
来源:https://dwz.cn/5hWgtEtT
完
●Java中Set集合是如何实现添加元素保证不重复的?●为什么不建议使用Date,而是使用Java8新的时间和日期API?●Spring Boot 定时任务 @Scheduled●如何选择消息队列?●初探微服务架构●从单体应用走向服务化●什么是微服务?●一条SQL查询语句是如何执行的?
觉得不错,点个在看~