Restful API 设计原则
前言
网络应用程序分为前端和后端两个部分。
当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备……),这也就意味着前端的开发代码、开发框架变得多种多样。因此,必须有一种统一的机制,方便不同的前端代码与后端进行通信。
这就导致了API构架的流行。REST是目前比较成熟的一套互联网应用程序的API设计理论。 它可以降低开发的复杂度,提高系统的可伸缩性,增强系统的可扩展性,简化应用系统之间的集成。
在这篇文照中,我整理了一些RESTful API的设计细节,探讨如何设计一套合理、好用的API。
注意:这篇文章只讨论设计原则,不是强制的要求或者标准(API 设计者可以根据实际情况实现部分内容,甚至实现出和某些原则相反的内容)。
定义
下面是一些本文中可能要使用的名词:
- Resource(资源):单个实例对象,例如一只动物
- 一个资源可以是一份文档、一张图片、一个与时间相关的服务(例如:洛杉矶今天的天气)等等。Roy Thomas Fielding认为资源是实体的概念性映射,而不是实体本身;我个人觉得资源是一种在网络上的抽象概念,更像是一种数据信息。
- Collection(集合):集合是一组同类的实例对象,例如一群动物。
- HTTP:一种网络的通信协议
- 客户端:可以创建HTTP请求的客户端应用程序
- 第三方开发者:将使用你的数据的开发者。
- 服务器:一个HTTP服务器或者应用程序,客户端可以跨网络访问它
- Endpoint(端点):服务器提供的一个URL,它标识了一个资源(Resource)或者集合(Collection)
- Idempotent(幂等性):多次重复操作得到的结果一样
- URL段:在URL里面用斜杠分隔的内容
使用 HTTPS
不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文传播,带来了三大风险。
- 窃听风险(eavesdropping):第三方可以获知通信内容。
- 篡改风险(tampering):第三方可以修改通信内容。
- 冒充风险(pretending):第三方可以冒充他人身份参与通信。
SSL/TLS协议是为了解决这三大风险而设计的,希望达到:
- 所有信息都是加密传播,第三方无法窃听。
- 具有校验机制,一旦被篡改,通信双方会立刻发现。
- 配备身份证书,防止身份被冒充。
使用HTTP或者HTTPS和Restful API本身没有很大的关系,但是对于增加网站的安全是非常重要的。特别如果提供的是公开 API,用户的信息泄露或者被攻击会严重影响网站的信誉。
使用SSL可以减少鉴权的成本:你只需要一个简单的令牌(token)就可以鉴权了,而不是每次让用户对每次请求签名。
NOTE:不要让非SSL的url访问重定向到SSL的url。
API 域名和版本
无论你在设计什么系统,也不管你事先做了多么详尽的计划,随着时间的推移和业务的发展,你的程序总会发生变化,数据关系也会发生变化,资源可能会被添加或者删除一些属性。
但是在Restful的设计思想中,资源描述和资源实体是分开的,而设计REST API是基于资源描述。当资源实体发生变更时,只要修改资源描述和资源实体的映射,就能保证资源描述不变,进而保证所设计的API不变,所有使用API的第三方程序也不需要做任何修改。
在 url 中指定 API 的版本是个很好地做法。如果 API 变化比较大,应该尽量把 API 设计为子域名,比如
https://api.github.com/v3
如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下,比如:
https://example.com/api
当然还有另一个常用的解决办法就是把版本号放在请求首部中(HTTP请求的accept字段),根据多年与第三方开发人员打交道的经验,把版本号放在URL里要比放在请求的首部中更容易实现和使用,如上面所示,github就是采用将版本号放到URL的方法。
资源与端点
上文中提到,在 REST 构架的设计中,系统中的所有事物都被抽象为资源,而URI是这个资源的唯一标识。
- 在一个文档系统中