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时。

沈子平
183 声望17 粉丝

慢慢积累,一切都不会太晚.