REST API最佳实践
REST渐渐成为向外曝露服务的通用方式。之所以这么流行的原因主要是简单,易于使用,使用HTTP协议(REST可以用于所有协议,但应用最广泛的是HTTP)等。但是所有向外暴露的资源都被认为是REST是一种误解,是不正确的。在这里,我会向你介绍一些在你实现自己的REST API时你应该谨记的最佳实践。
扩展阅读:REST vs SOAP
下面是一个导读列表
- 1.名词,不要用动词
- 2.使用复数
- 3.文档
- 4.接口版本
- 5.分页
- 6.使用SSL
- 7.HTTP方法
- 8.有效的使用HTTP状态码
1.名词,不要动词
REST API开发人员的一个不好的习惯是使用动词来命名REST接口。你应该使用名词来替代动词。
场景
要新建一个REST web services用来获取印度的农民数据。同时,该接口也可以获取其他的信息比如收入,农作物名称,地址等和农民相关的数据。每一个农民都指派了unique ID。
同样的,服务也需要提供农民关联的农作物的信息的接口。
最佳实践
为所有的操作提供单一的endpoint.在下面的例子中,我们为所有的操作(get,add,update,delete)提供了一个endpoint "/farmers",通过不同的HTTP method 来调用不同的操作,下面还会详细介绍。
- /farmers
- /crops
尽量避免
尽量避免在命名中使用动词。推荐在数据中或者HTTP method提现操作。不要像下面这样命名REST
- /getFarmers
- /updateFarmers
- /deleteFarmers
2.使用复数
使用复数来命名REST服务。这是在REST设计者讨论中的热门话题。
最佳实践
- /farmers
- /farmers/{farmer_id}
尽量避免
- /farmer
- /farmer/{farmer_id}
注意
在实践中不要混用单数或者复数命名,虽然我说使用复数是最佳实践,但是如果你坚持使用单数,那么就在所有的服务上执行相同的策略。
3.文档
对软件实现文档化是非常好的习惯,对REST API也是同样。如果你写下了有用的文档,这将使其他开发者收益。对于REST API的常见注释,主要是列出API的endpoints,对每一个endpoint描述其支持的功能列表。有很多工具可以自动完成这件事情。这些工具有:DRF DOCs,Swagger,Apiary
4.接口版本
任何软件都会进化,对于API的每一个比较大的变动,可能需要不同的版本号。如果对API版本化,是REST开发者社区的热门话题。一般来说,有两种方法来将接口版本化
URI 版本化
使用URI的简单例子是
- http://host/v2/farmers
-
http://host/v1/farmers
主要的缺点有 - 破坏了存在的URI,所有的客户端需要跟着改
- 增加了需要管理的URI,这会导致增加客户端保存多个URI版本的缓存增加。会降低缓存的命中率,也会降低应用的运行效率。
- 非常不具弹性,不能简单的修改单个资源或者资源的子集。
媒体类型版本化
这个方法是通过在request的header上增加接口的版本信息。当我们改变URI的资源类型和语言时,我们要修改request的头信息。这个方法对于REST API的版本化是最好的选择。
媒体类型不再是application/json,而是像下面这样:
GET /account/5555 HTTP/1.1
Accept: application/vnd.farmers.v1+json
HTTP/1.1 200 OK
Content-Type: application/vnd.farmers.v1+json
通过这个方法,客户端可以选择要请求的版本。虽说这个方法比URI版本化来得好,但是通过header传输的不同版本的请求缓存的复杂度也大大上升了。简单的说,当客户端基于URI做缓存,这是简单的,但是通过媒体类型来缓存就增加了复杂性。
5.分页
通过HTTP发送大量数据是一个糟糕的做法。这会引发性能问题,因为序列化大的json对象非常耗时耗资源。建议将结果分页并提供前后的导航链接。
如果你在应用中使用分页,一个较好的做法是使用Link HTTP header option. 这篇文章 link from GitHub应该有用。会帮你打开思路。
6.使用SSL
使用SSL是必须的。REST API必须得到SSL的保护。引用在因特网上发布,无法保证安全的接入。随着越来越多的计算机犯罪事件,我们必须以正确的方式来保护我们的应用。
API的安全已经有成熟的工业标准。不要使用简单的认证机制。可以使用Oauth1.0a或者Oauth2来使接口变得安全。建议使用最新的Oauth2。
7.HTTP方法
当你知道各个HTTP方法所扮演的角色后,将操作映射到HTTP的方法是非常简单的。在前面提及要使用HTTP方法来表示资源的操作,而不是通过不同的服务名字。本节会大致介绍各个HTTP方法的行为模式。
下面两点是在使用HTTP方法前需要考虑的两个方面:
- 安全 :当调用方法时不会改变资源的状态,就认为该HTTP方法时安全的。比如,当通过GET方法获取数据,因为不会修改数据,所以这个方法就是安全的。
-
幂等 :调用资源多次,所获得的回应是相同的,这就是幂等。比如,当你尝试更新数据,每次的返回都相同。
不是所有的方法都是安全和幂等的。下面是一个可以用在REST API调用的列表,表示各个方法安全和幂等的情况GET 安全 幂等 POST 不安全 不幂等 PUT 不安全 幂等 DELETE 不安全 幂等 OPTIONS 安全 幂等 HEAD 安全 幂等
下面是各个方法的简要说明,在使用的时候请参考:
- GET:这个方法是安全且幂等的。常用于获取数据。
- POST:这个方法不安全也不幂等。常用于创建资源。
- PUT:这个方法是幂等。常用于更新资源。需要避免使用POST来更新资源。
- DELETE:常用语删除资源,但是这个方法并不是对所有的请求幂等的。
- OPTIONS:这个方法不是用来操作资源的。当客户端不清楚对应的资源有哪些操作时,使用该操作获得资源的表示。
- HEAD:可以用来查询一个资源。和GET非常想,但是就如在HTTP的规定所解释的,HEAD方法必须在header中发送请求和获得回应。
8.有效的使用HTTP状态码
HTTP定义了非常多的状态码,这些码对客户端非常有意义。你的REST API可以有效的使用这些状态码来帮助客户端。下面是状态码的列表和摘要:
- 200 OK - 表示对应的GET,PUT,PATCH 或 DELETE操作成功。也可以用于POST表示没有创建成功。
- 201 Created - 表示POST创建成功
- 204 No Content - 表示一个成功的响应,body为空(比如 delete)
- 304 Not Modified - HTTP缓存
- 400 Bad Request - 表示request错误,比如body解析出错
- 401 Unauthorized - 提供了错误的认证信息。可以在这个错误之后触发认证功能。
- 403 Forbidden - 当认证成功,但是对应的用户没有对应资源的权限时。
- 404 Not Found - 表示请求一个并不存在的资源
- 405 Method Not Allowed - 一个认证的用户,调用了他所不允许使用的方法时。
- 410 Gone - 表示资源已经不可用。比如调用了一个老的API版本。
- 415 Unsupported Media Type - request提供了错误的content type
- 422 Unprocessable Entity - 验证错误
- 429 Too Many Requests - 因为负载限制,拒绝request时。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。