查看原文
其他

RESTful API 最佳实践

悠悠i 武培轩 2022-03-15

点击上方“武培轩”,选择“设为星标”

技术文章第一时间送达!

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 中如何比较日期?JVM类加载过程与双亲委派模型JVM GC算法JVM内存模型
Java中Set集合是如何实现添加元素保证不重复的?为什么不建议使用Date,而是使用Java8新的时间和日期API?Spring Boot 定时任务 @Scheduled如何选择消息队列?初探微服务架构从单体应用走向服务化什么是微服务?一条SQL查询语句是如何执行的?

觉得不错,点个在看~

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存