RESTful架构API风格与相关规范

一、概述:

  1. RESTful架构,就是目前最流行的一种互联网软件架构。REST是Representational State Transfer词组的简写,即“表现层状态转化”。代表(互联网资源)表现层状态转化。

  2. REST是Roy Fielding博士在2000年在其论文中第一个提到的,因为他是互联网行业内一个重要的人物(HTTP 1.0/1.1协议的主要设计者、Apache开源基金会的第一任主席),所以引起了人们的关注,并且对互联网产生了深远的影响。

  3. RESTful不是一个标准,但是一种规范。现在很多软件使用使用前后端分离的应用结构,它结构清晰、符合标准、易于理解、扩展方便。前端(H5、Android、iPhone、小程序)往往通过调用API的方式与后端进行数据交换。那么,符合RESTful规范的软件架构的API我们可称之为RESTful APl。如微博开放API和Github开放API就严格遵循了RESTful规范。

以上是对RESTful架构的概述,在本文中,我将使用自己的理解完整的表述RESTful的规范,以及如何设计符合RESTful规范的API。实际上,在对计算机技术的理解中,一百个人可能会有一百种理解方式,尽管见仁见智,但我们的目的都是把技术当作工具,去实现我们的程序功能。如果在本文中的描述有所错误,或您有所不解,欢迎留言评论!

下面将分为将分为三个内容,展开描述我对RESTful的理解:

1.理解 RESTful
2.RESTful API架构规范
3.RESTful API 设计示例

二、理解RESTful

要理解RESTful,我们需要从每一个词开始理解。Roy Fielding将他对互联网软件的架构原则命名为REST,即Representational State Transfer的缩写,代表(资源)表现层状态转化。如果一个软件架构符合REST原则,就称它为RESTful架构。

1. 资源(Resources)

我们在互联网软件开发中,我们所说的“资源”是指在互联网中某一个节点的具体信息,如一段文本、一张图片、一个视频、一个压缩包、一个程序安装包等等。在互联网中,我们可以使用URI(统一资源定位符)来表示每一个具体的资源,因此,每一个互联网资源都一个独一无二的URI地址。

2. 表现层(Representational)

“资源”是一种信息的实体,实际上,资源有很多表现形成,如一段文本,我们可以使用普通的txt格式来表示,也可以用JSON格式来表示,还可以使用XML格式来表示。“资源”的具体表现形式我们就叫做表现层。在HTTP协议中,规定了头信息中的Content-Type字段来描述具体的资源表现形式。如“Content-Type: text/html”表示为html格式的文本数据,而“Content-Type: text/json”表示为JSON格式的文本数据。

1. 状态转化(State Transfer)

HTTP是一种无状态的网络协议,如果客户端要操作服务器,必须通过一种手段通知服务器进行“状态转化”,而这种状态改变建立在“表现层”之上,这就是“表现层状态转化”。在HTTP协议中,客户端通过发送相应的请求告知服务器实现某种状态的改变。客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作。

综上所述,我们可以总结一下RESTful的特点:
a. 每个互联网资源都有一个唯一的URI地址;
b. 通过操作资源的表现形式来操作资源;
c. 一般情况下使用JSON格式来表示具体的数据;
c. 使用HTTP协议进行客户端与服务端之间的交互,从客户端到服务端的每个请求都必须包含理解请求所必需的信息;
d. 客户端使用GET、POST、PUT、DELETE 4个表示操作方式的动词对服务端资源进行“状态”操作。

三、RESTful API架构规范

REST并没有明确的设计标准,可以说RESTful是一种设计风格的规范化。在RESTful API设计中,不同的组织可能还存在不同的设计风格规范,但是整体上RESTful的风格规范是一致的。

也正是因为有了一致的风格规范,让读API的人更好地理解API,甚至不用阅读文档,就知道API要实现的某个资源的某种“状态转化”。根据Github开放API或者微博开放API的设计风格。下面是我总结的RESTful API的相关风格规范,今后我将使用此规范进行API开发。

1. 协议

客户端与服务器之间使用HTTP或者HTTPS协议进行通信。

2.域名

应当尽量将API程序部署到专有的域名之下,如:

https://api.demo.com

如果API比较简单,或者不考虑进行扩展,应当放在项目的子模块中,如:

https://demo.com/api/

3.API版本

应当将API版本放在URL中,如微博开放API就将版本号放在URL中:

http://api.weibo.com/2/

如果我们把版本号理解成资源的不同表述形式的话,API版本应放在HTTP请求头Accept字段中,如github中的开放API

Accept: application/vnd.github.v3

可能github考虑很多因素,所以把请求的API版本放到HTTP请求头里了。实际上,如果我们想要快速的开发一个API程序,使用第一种形式会更加直观与方便。

4.路径

对于不同的资源,都有一个唯一的URL地址,每一个URL地址代表一种资源,所以网址中应当是名称,不能是动词,而且名词应当与数据库表名对应。一般来说,数据库中保存的是数据集合,所以URL中对应的资源应当是名词复数。

如Github开放API中,列出一个组织的项目集合:

https://api.github.com/orgs/:org/projects

在上面URL中,orgs代表组织集合,而:org代表集体的组织名,projects代表具体的资源

5.HTTP动词

对于资源的某种具体操作类型,需要客户端发送不同的HTTP动作来完成。
常用的五个HTTP动词已经对应操作如下:

* GET(Retrieve):从服务器取出资源(一项或多项);
* POST(CREATE):在服务器新建一个资源;
* PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源);
* PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性);
* DELETE(DELETE):从服务器删除资源。

实际上,最常用的额HTTP动词原先只有4个,即GET、POST、PUT、DELETE,PATCH方法是新引入的,是对PUT方法的补充,用来对已知资源进行局部更新。

有时候,只需要修改一个属性,开发者通常(为图省事)把一个包含了修改后完整信息传给后端,做完整更新。但实际上如果需要考虑性能优化,是有必要做局部更新的。

6.过滤

在获取服务器资源的时候,大部分情况是需要进行过滤的,而不是获取数据库中的完整集合。这时候需要设置过滤条件,我们可以将过滤条件作为参数拼接到URL中。如下:

?limit=10  # 指定获取10条信息集合
?page=1&limit=10  # 指定每页10条信息,获取第1页信息集合
?limit=10&deleted=true  # 获取数据库中已经标志为删除的10条信息集合

7.返回

使用相应的HTTP状态码,将结果告知客户端,以下是常用的HTTP状态码以及状态描述:

状态码 描述 备注
200 OK - 成功
204 NO CONTENT - 无内容 DELETE返回204状态码,表示资源已经不存在
303 See Other - 其他 表示参考另一个 URL,此时应当返回URL链接
400 bad request - 服务器不理解客户端的请求(如,参数错误)
401 Unauthorized - 没有通过身份验证
403 Forbidden - 没有访问权限
404 Not Found - 资源不存在,或不可用
405 Method Not Allowed - 对于此HTTP方法没有权限
409 conflict - 通用冲突 如被请求的资源与其当前状态之间存在冲突,请求无法完成
410 Gone - 资源不存在,或不可用
415 unsupported media type - 不支持的媒体类型 如服务器需要客户端使用JSON数据请求,而客户端使用XML进行请求
429 Too Many Requests - 请求次数超过限额
500 internal server error - 服务器通用错误 如果客户端请求有效,服务器处理时发生了意外
503 Service Unavailable - 服务端当前无法处理请求 如网站正在维护,服务器无法处理请求
  • 正常:如果正常返回数据,应当使用msg或者其他关键字作为键名返回给客户端,如下:
{
"data":[
    "user_id":1,
    "name":"张三",
    "token":"csdcnsdvndsijudsao",
],
"message":"OK",
"code":200
}
  • 错误:如果发生错误,应当使用error作为错误信息的键名返回给客户端
{
"error":"Unauthorized",
"code":401
}

针对不同操作,服务器向用户返回的结果应该符合以下规范:

GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档

8.Hypermedia API

RESTful API最好做到Hypermedia,即超媒体,在返回结果中提供链接,连向其他API方法或者一些文档,使得用户不查文档,也知道下一步应该做什么。如Github就做到了Hypermedia,使用GET方式请求 https://api.github.com ,会返回一系列的链接地点:

{
  "current_user_url": "https://api.github.com/user",
  "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}",
  "authorizations_url": "https://api.github.com/authorizations",
  "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}",
  "commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}",
.....

四、RESTful API设计示例

RESTful API风格主要体现在URL中,接下来,我们通过一个示例,来完成RESful API的URL制定。假设我们要开发一个简单的博客系统,要给H5、Android、iPhone、小程序提供一套统一的接口。那么预设功能与对应URL已经请求方式如下:

模块 功能 URL HTTP请求方式
用户 用户注册 http://api.demo.com/1.0/users/register POST
用户 用户登录 http://api.demo.com/1.0/users/login POST
文章 发表文章 http://api.demo.com/1.0/articles POST
文章 查看文章 http://api.demo.com/1.0/articles/:id GET
文章 修改文章 http://api.demo.com/1.0/articles/:id PUT
文章 删除文章 http://api.demo.com/1.0/aritcles/:id DELETE

到此结束。

本文为作者原创文章,禁止转载,原作者:https://phy.xyz

推荐阅读更多精彩内容

  • 去年有段时间得空,就把谷歌GAE的API权威指南看了一遍,收获颇丰,特别是在自己几乎独立开发了公司的云数据中心之后...
    骑单车的勋爵阅读 12,374评论 0 39
  • API定义规范 本规范设计基于如下使用场景: 请求频率不是非常高:如果产品的使用周期内请求频率非常高,建议使用双通...
    有涯逐无涯阅读 1,409评论 0 6
  • 一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式。”但是在要求详细讲述它所提出的各个约束,以及如...
    时待吾阅读 1,964评论 0 17
  • 一、什么是API? API(Application Programming Interface,应用程序编程接口)...
    Fairy_妍阅读 16,098评论 1 17
  • 译者:知秋(极乐科技专栏作者)来源:https://zhuanlan.zhihu.com/p/24592119 当...
    极乐君阅读 671评论 0 15