RESTful 架构 & RESTful API 设计指南

简介

越来越多的人开始意识到,网站即软件,而且网站是一种新型的软件。

这种"互联网软件"采用客户端/服务器模式,建立在分布式的体系上。网站开发,完全可以采用软件开发的模式。

RESTful 架构,就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。

REST(Representational State Transfer,简称 REST)描述了一个架构样式的网络系统,比如 web 应用程序。

它首次出现在 2000 年 Roy Thomas Fielding 的博士论文中,Fielding是一个非常重要的人,他是 HTTP 协议(1.0 版和1.1 版)的主要设计者、Apache服务器软件的作者之一、Apache 基金会的第一任主席。

在目前主流的三种 Web 服务交互方案中,REST 相比于 SOAP(Simple Object Access protocol,简单对象访问协议)以及 XML-RPC 更加简单明了。

无论是对 URL 的处理还是对 Payload 的编码,REST 都倾向于用更加简单的方法来设计和实现。

值得注意的是,REST 并没有一个明确的标准,而更像是一种设计风格。

REST 原则

REST 指的是一组架构的约束条件和原则。如果一个架构符合 REST 原则,就称它为 RESTful 架构。

资源(Resources)

REST 的名称"表现层状态转化"中,省略了主语。"表现层"其实指的是"资源"(Resources)的"表现层"。

所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。

资源可以是文本、图片、数据库记录、算法等。每个资源都使用 URI (Universal Resource Identifier) 得到一个唯一的地址,或者说,每种资源都对应一个特定的 URI。

URI 是资源的唯一识别符,只代表网络中资源的地址(位置),而不代表资源的表现形式。

表现层(Representation)

资源是一种实体,它可以有多种表现形式。我们把资源具体呈现出来的形式,叫做它的表现层(Representation)。

资源的表现形式,可以是 html、json、xml 等,表现形式由 HTTP 请求头信息中的Accept 和 Content-Type 字段来指定。

状态转化(State Transfer)

访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。

HTTP 协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。

如果客户端想要操作服务器,就必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是基于表现层的,所以就是"表现层状态转化"。

客户端用到的手段,只能是 HTTP 协议。具体来说,就是利用 HTTP 的动词来进行操作资源。

HTTP 动词

对于资源的具体操作类型,由 HTTP 动词来表示。

HTTP 动词对应的操作如下:

  • GET: 获取资源(一个或多个)。
  • POST: 创建资源。
  • PUT:更新资源(客户端提供更新后的完整资源)。
  • PATCH:更新资源(客户端提供改变的属性)。
  • DELETE:删除资源。
  • HEAD:获取资源的元数据。
  • OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。

幂等性

幂等性是指应用程序中,同一段代码多次执行和一次执行的结果完全一致。

对于上述 HTTP 动词,GET、PUT、PATCH、DELETE、HEAD 和 OPTIONS 应该是幂等的;而 POST 是非幂等的。

综述

综合上面的解释,我们总结一下什么是 RESTful 架构。

RESTful 架构遵循以下几个原则:

  • 网络中的所有实体都是资源,每一种资源都对应一个 URI。
  • 客户端和服务器之间,传递这种资源的某种表现层。
  • 客户端通过 HTTP 动词,对服务器端的资源进行操作,实现"表现层状态转化"。

RESTful API 设计指南

符合 RESTful 架构 的 API 设计,就是 RESTful API。

由于 RESTful 架构的简单性和可扩展性,RESTful 风格的 API 已经逐渐取代了 RPC 风格的 API。

通信协议

RESTful API 采用的通信协议为 http 或 https。

域名

应该尽量将 API 部署为专有域名或放在主域名下。

https://api.example.com/



https://example.com/api/

API 的版本

应该将 API 的版本号放入 URL。

https://api.example.com/v1/

另一种做法是,将版本号放在 HTTP 头信息中,但不如放入 URL 中方便、直观。

路径(path)

路径又称为终点(endpoint),用来表示 API 的具体名称,它是一个相对于服务器地址(https://api.example.com/v1/ )的相对路径。

在 RESTful 架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表名对应。

一般来说,数据库中的表都是同种记录的集合(collection),所以 API 中的名词也应该使用复数。

举例来说,文章 API 接口,用于提供文章相关的 API,它的路径(终点)应该设计为:

/articles

/articles/{id}

那么,API 的完整路径为:

http://apidemo.test/api/v1/articles

http://apidemo.test/api/v1/articles/{id}

HTTP 动词

对于资源的具体操作类型,由 HTTP 动词来表示。

HTTP 动词对应的操作如下:

  • GET: 获取资源(一个或多个)。
  • POST: 创建资源。
  • PUT:更新资源(客户端提供更新后的完整资源)。
  • PATCH:更新资源(客户端提供改变的属性)。
  • DELETE:删除资源。
  • HEAD:获取资源的元数据。
  • OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。

其中,GET、POST、PUT、PATCH 和 DELETE 是最常用的五个动词。

下面是一些例子:

  • GET /articles 获取所有的文章列表
  • POST /articles 创建新文章
  • GET /articles/{id} 获取指定的文章
  • PUT /articles/{id} 更新指定的文章(提供该文章的全部信息)
  • PATCH /articles/{id} 更新指定的文章(提供该文章的部分信息)
  • DELETE /articles/{id} 删除指定的文章

过滤信息

如果记录数量太多,服务器不可能将它们一次返回给用户。API 应该提供参数,来过滤返回结果。

下面是一些常见的参数。

  • ?limit=10:指定返回记录的数量
  • ?offset=10:指定返回记录的开始位置。
  • ?page=2&per_page=100:指定第几页,以及每页的记录数。
  • ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序的顺序。
  • ?user_id=1:指定筛选条件。

状态码

服务器向客户端返回的状态码和提示信息,常见的有以下这些(方括号中是该状态码对应的HTTP动词)。

  • 200 OK - [GET]:服务器成功返回用户请求的数据。
  • 201 CREATED - [POST/PUT/PATCH]:创建或修改数据成功。
  • 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)。
  • 204 NO CONTENT - [DELETE]:删除数据成功。
  • 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作。
  • 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
  • 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
  • 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作。
  • 406 Not Acceptable - [GET]:用户请求的格式不存在(比如用户请求 JSON 格式,但是只有 XML 格式)。
  • 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到。
  • 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
  • 500 INTERNAL SERVER ERROR - [*]:服务器内部发生错误,用户将无法判断发出的请求是否成功。

错误处理

如果状态码是 4xx,就应该向用户返回出错信息。一般来说,返回的信息中将 error 作为键名,出错信息作为键值即可。

{
    error: "Invalid API key"
}

返回结果

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

  • GET /articles 返回文章对象列表(数组)
  • POST /articles 返回新生成的文章对象
  • GET /articles/{id} 返回单个文章对象
  • PUT /articles/{id} 返回更新后的文章对象
  • PATCH /articles/{id} 返回更新后的文章对象
  • DELETE /articles/{id} 返回空对象

数据格式

服务器返回的数据格式,应该尽量使用 JSON,避免使用 XML。

API 认证

API 的身份认证,推荐使用 OAuth 2.0 标准。

当然,你也可以使用 JWT,甚至是自定义的 api_token。

猜你喜欢

转载自blog.csdn.net/lamp_yang_3533/article/details/80471372