关于RESTful风格接口设计的理解
RESTful的概念
表现层状态转换(英语:Representational State Transfer,缩写:REST)是Roy Thomas Fielding博士于2000年在他的博士论文[1]中提出来的一种万维网软件架构风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息。表现层状态转换是根基于超文本传输协议(HTTP)之上而确定的一组约束和属性,是一种设计提供万维网络服务的软件构建风格。符合或兼容于这种架构风格(简称为 REST 或 RESTful)的网络服务,允许客户端发出以统一资源标识符访问和操作网络资源的请求,而与预先定义好的无状态操作集一致化。因此表现层状态转换提供了在互联网络的计算系统之间,彼此资源可交互使用的协作性质(interoperability)。相对于其它种类的网络服务,例如SOAP服务,则是以本身所定义的操作集,来访问网络上的资源。
老实说,到现在我也不明白,为什么要用这种让人摸不着头脑的翻译。直到最近,在给一个后辈讲解的时候,突然发现以前设计的接口地址是多么的随心所欲,有时变量在问号前,有时候变量在问号后。所以趁现在还有所感悟,记录一下我的心得。
RESTful接口的设计
RESTful接口的表现形式
GET http://api.sample.com/v1/resources?query=<query>
上面是一个接口例子,它可以被分为4个部分:
1. GET
部分
该部分表示接口与服务器的交互方法。最常见的有4种:GET
、POST
、PUT
、DELETE
,分别对应着查询、新增/插入、修改、删除四种操作。有了这个操作定义之后,我们无需再往path里补充任何动词。
2. http
部分
这个部分是传输协议。常见的有HTTP
、HTTPS
、 FTP
等,表示任何物理介质中允许两个或多个在传输系统中的终端之间传播信息的系统标准。这个部分按实际需求选择即可。
3. api.sample.com/v1/resources
部分
这个部分我把它称为PATH
。具体细分还可以分为2-3个部分:域名、版本号(可选)、资源名。域名就不多说了,版本号在定义里原来是没有的,但加入版本号的好处是可以在不破坏原有流程的基础上进行迭代,使旧流程可以更安全稳定地过渡到新流程中。
接下来我想重点谈谈资源名部分,一般来说这个地方应该是服务名加上数据表名或是文件名,以表示一组资源。它应该是一个不带动词的名词。同时,你也可以带上这个id号,以进一步区分单个资源。
但是在内部开发中,由于需要对同一个资源进行不同的加工,用表名或是文件名作为资源名是远远不够的。故也可以用具体的业务名作为资源名,但仍然要满足它是一个名词的要求。
我遇到一个业务,需要设计获取农批市场肉菜分析图表的接口,这个时候使用/{retail | wholesale}/{meat | vegetable}/{stat | trends}
作为资源名也是不错的选择,这种按属性分隔的设计可以很清楚明了地区分各个接口的作用,同时又不会使接口显得杂乱无章。
4. query
部分
顾名思义,这个部分用作补充查询条件,表现为跟在?
后面,用&
把各个参数连接起来。这一部分常用于GET
、PUT
和DELETE
3种交互操作中,起到类似于sql里面的过滤条件作用。当然,query参数也可以作为数据加工的指示条件来使用。
*. 并没有在例子中体现的body
部分
这个部分常出现在POST
和PUT
方法中,作为它们的传参方法。POST
有4种常见提交数据方式,RESTful提倡使用application/json
作为我们的body提交类型。在设计body的时候,要注明字段的属性如:字段名、是否必传、字段类型、默认值和字段说明等。
一些补充说明
- 在设置
path
、query
、body
、response
变量名时,切记避开一些编程语言关键字如type
、in
等,不如说在任何时候都要尽量避免使用它们。 - 在
path
中应该使用-
替代_
,这样才符合url的规范,而query
中则要反之。 - 在设计多个类似接口时,尽量使它们的用法保持一致。包括query名与作用一致,返回结果的结构一致,相同或近似字段名一致等。这样可以大大减轻双方后期许多的工作量!