什么是REST/RESTful API?

文章内容及目的(CONTENT & OBJECTIVE)

1.了解什么是REST
2.了解如何使用REST范式/风格设计各端

REST(REPRESENTATIONAL STATE TRANSFER)

REST(英文:Representational State Transfer)是一种无状态资源传输体系范式,用在服务端和客户端之间提供标准,从而使系统之间的通信更容易。与REST兼容的系统,通常称为RESTful系统,其特点是它们是无状态的,并且分离了客户端和服务端的关注点。我们将讨论这些术语的含义以及它们为什么是Web等服务实现前后端分离的有益特性。

客户端与服务端分离(SEPARATION OF CLIENT AND SERVER)

在REST架构范式中,客户端的实现和服务端的实现可以独立完成,而彼此不必知道对方。这意味着客户端的代码可以在不影响服务端操作的情况下随时更改,服务端的代码可以在不影响客户端操作的情况下更改。
只要双方都知道要向对方发送什么格式的消息,它们就可以保持模块化和分离。将用户界面关注点与数据存储关注点分开,通过简化服务端组件,我们改进了跨平台的接口的灵活性,并提高了可伸缩性。此外,分离允许每个组件独立地发展。

通过使用一个REST接口,不同的客户端访问相同的REST端点,执行相同的操作,并接收相同的响应。

无状态性(STATELESSNESS)

遵循REST范式的系统是无状态的,这意味着服务端不需要知道客户端处于什么状态,反之亦然。这样,服务端和客户端都可以理解接收到的任何消息,即使没有看到以前的消息。这种无状态限制是通过使用资源而不是命令来实现的。资源是网络中的名词-它们描述任何对象、文档或东西,您可能需要存储或发送到其他服务。

因为REST系统通过对资源的标准操作进行交互,所以它们不依赖于接口的实现。

这些约束有助于RESTful应用程序实现可靠性、快速性能和可伸缩性,因为这些组件可以在不影响整个系统的情况下进行管理、更新和重用,甚至在系统运行期间也是如此。

现在,我们将探讨在实现RESTful接口时,客户端和服务端之间的通信实际上是如何发生的。

客户端和服务端之间的通信(COMMUNICATION BETWEEN CLIENT AND SERVER)

在REST体系结构中,客户端发送请求以检索或修改资源,而服务端则向这些请求发送响应。让我们看看发出请求和发送响应的标准方法。

提交请求(MAKING REQUESTS)

REST要求客户端向服务端发出请求,以便检索或修改服务端上的数据。请求通常包括:

  • 一个HTTP动词,定义要执行的操作类型.
  • HTTP的头域,允许客户端传递有关请求的头信息。
  • 资源的路径
  • 包含数据的可选消息正文

1.HTTP动词(HTTP VERBS)

我们在请求中使用5个基本HTTP动词来与REST系统中的资源交互:

  • GET (SELECT):从服务端检索特定资源,或资源列表。
  • POST (CREATE):在服务端上创建一个新的资源。
  • PUT (UPDATE):更新服务端上的资源,提供整个资源。
  • PATCH (UPDATE):更新服务端上的资源,仅提供更改的属性。
  • DELETE (DELETE):从服务端删除资源。
    这里有两个较少知名的HTTP动词:
    • HEAD - 检索有关资源的元数据,例如数据的哈希或上次更新时间。
    • OPTIONS - 检索关于客户端被允许对资源做什么的信息。
    • 一个好的RESTful API将使用四个半HTTP动词,允许第三方与其数据进行交互,并且不会将动作/动词作为URL段。

通常,GET请求可以被缓存(通常是!)在浏览器,例如将缓存请求头用于第二次用户的POST请求。 HEAD请求基本上是一个没有响应主体的GET,并且也可以被缓存。

2.头信息和接收参数(HEADERS AND ACCEPT PARAMETERS)

在请求头中,客户端发送它能够从服务端接收的内容类型。这称为Accept字段,它确保服务端不会发送客户端无法理解或处理的数据。
例如,包含HTML的文本文件将使用text/HTML类型指定。如果此文本文件包含CSS,则将其指定为text/CSS。通用文本文件将被表示为文本/纯文本。但是,这个默认值text/plain并不是一个全部捕获的值。如果客户端需要文本/css并接收到文本/plain,则它将无法识别内容。内容类型的选项是MIME类型。

MIME类型,MIME(Multipurpose Internet Mail Extensions,多功能因特网邮件扩展)原来是用来判断电子邮件附件的格式而设计的一个字符串,后来演变为网络文档,及企业网和Internet上的其他应用程序中的文件格式的规范。
MIME类型是由一个媒体类型和一个子类型组成。媒体类型和子类型用一个斜杠(/)分隔开,例如text/css,它会告诉浏览器文件是纯文本文件,也是一个CSS样式表。每一个媒体类型都表示一种文件类型,媒体类型及说明见下表。

其他类型和常用子类型:

  • image — image/png, image/jpeg, image/gif
  • audio — audio/wav, image/mpeg
  • video — video/mp4, video/ogg
  • application — application/json, application/pdf,
  • application/xml, application/octet-stream

例如,访问服务端上项目资源中id为23的资源的客户端可能会发送如下GET请求:

1
2
GET /articles/23
Accept: text/html, application/xhtml

在本例中,Accept header字段表示客户机将接受text/html或application/xhtml格式的内容。

3.资源路径(PATHS)

请求必须包含应对其执行操作的资源的路径。在restfulapi中,路径的设计应该帮助客户端知道发生了什么。

按照惯例,路径的第一部分应该是资源的复数形式。这使得嵌套路径易于阅读和理解。

像fashionboutique.com/customers/223/orders/12这样的路径在它指向什么方面是清楚的,即使您以前从未见过这种特定的路径,因为它是层次化的描述明确的。我们可以看到,对于id为223的客户,我们正在访问id为12的订单。

路径应包含定位所需资源的特定信息。当引用资源的列表或集合时,无需向fashionboutique.com/customers路径中的POST请求添加id,因为服务器将为新对象生成id。

如果我们试图访问一个资源,我们需要在路径上附加一个id。例如:GET fashionboutique.com/customers/:id-检索客户资源中具有指定id的项目。DELETE fashionboutique.com/customers/:id-删除客户资源中具有指定id的项。

发送响应(SENDING RESPONSES)

1.内容类型(CONTENT TYPES)

在服务端向客户端返回数据的情况下,服务端必须在响应的头中包含一个内容类型。此内容类型标题字段提醒客户端它在响应正文中发送的数据类型。这些内容类型是MIME类型,就像它们在请求头的accept字段中一样。服务端在响应中发回的内容类型应该是客户端在请求的accept字段中指定的选项之一。

例如,当客户端使用此GET请求访问项目资源中id为23的资源时:

1
2
GET /articles/23 HTTP/1.1
Accept: text/html, application/xhtml

1
2
HTTP/1.1 200 (OK)
Content-Type: text/html

这意味着请求的内容正以text/html的内容类型返回到响应体中,客户端表示可以接受。

2.响应状态码(RESPONSE CODES)

服务端的响应包含状态码,用于提醒客户端有关操作成功的信息。作为一名开发人员,您不需要知道每个状态码(其中有许多),但您应该知道最常见的状态代码以及如何使用它们:

  • 200 OK - [GET]
    客户端从服务器请求数据,服务器为它们找到它(等幂)
  • 201 CREATED - [POST / PUT / PATCH]
    客户端提供了服务器数据,并且服务器创建了一个资源
  • 204 无内容 - [删除]
    客户端要求服务器删除资源,并且服务器将其删除
  • 400 无效请求 - [POST / PUT / PATCH]
    客户端给服务器的数据不良,服务器没有做任何事情(幂等)
  • 404错误
    客户端引用了一个不存在的资源或集合,并且服务器什么也不做(幂等)
  • 500内部服务器错误
    服务器遇到错误,并且客户端不知道请求是否成功

3.响应状态码范围(RESPONSE CODES RANGE)

  • 1xx 范围保留用于底层HTTP的东西,你很可能永远也用不到。
  • 2xx 范围保留用于成功消息,尽可能确保您的服务器尽可能多地向客户端发送这些消息。
  • 3xx 范围保留用于重定向。大多数API不使用这些请求很多(不像SEO人使用它们那么频繁),然而,较新的超媒体风格API将更多地使用这些请求。
  • 4xx 范围保留用于响应客户端做出的错误,例如。他们提供不良数据或要求不存在的东西。这些请求应该是幂等的,而不是更改服务器的状态。
  • 5xx 范围的状态码是保留给服务器端错误用的。这些错误常常是从底层的函数抛出来的,甚至开发人员也通常没法处理,发送这类状态码的目的以确保客户端获得某种响应。当收到5xx响应时,客户端不可能知道服务器的状态,所以这类状态码是要尽可能的避免。

(EXAMPLES OF REQUESTS AND RESPONSES)请求和响应示例

假设我们有一个应用程序,允许您查看、创建、编辑和删除fashionboutique.com上的一家小型服装店的客户和订单。我们可以创建一个HTTP API,允许客户端执行以下功能:
如果我们想查看所有客户,请求如下:

1
2
GET http://fashionboutique.com/customers
Accept: application/json

可能的响应头如下所示:

1
2
Status Code: 200 (OK)
Content-type: application/json

然后是以application/json格式请求的客户数据。
通过提交据创建新客户:

1
2
3
4
5
6
7
8
POST http://fashionboutique.com/customers
Body:
{
“customer”: {
“name” = “Scylla Buss”
“email” = “scylla.buss@codecademy.org”
}
}

然后,服务器为该对象生成一个id,并将其返回给客户端,其响应头类似于:

1
2
201 (CREATED)
Content-type: application/json

要查看单个客户,我们需要指定该客户的id:

1
2
GET http://fashionboutique.com/customers/123
Accept: application/json

可能的响应头如下所示:

1
2
Status Code: 200 (OK)
Content-type: application/json

后面是application/json格式的id为23的客户资源的数据。
我们可以通过输入新数据来更新该客户:

1
2
3
4
5
6
7
8
PUT http://fashionboutique.com/customers/123
Body:
{
“customer”: {
“name” = “Scylla Buss”
“email” = “scyllabuss1@codecademy.com”
}
}

可能的响应头的状态代码为:200(OK),用于通知客户端id为123的项已被修改。
我们还可以通过指定该客户的id来删除该客户:

1
DELETE http://fashionboutique.com/customers/123

响应将有一个包含状态代码204(无内容)的头,通知客户端id为123的项已被删除,而正文中没有任何内容。

课后练习(PRACTICE WITH REST)

让我们想象一下,我们正在建立一个照片收集网站,要做一个API来跟踪不同用户、用户空间和用户空间的照片。此网站有index.html和style.css。每个用户都有用户名和密码。每张照片都有一个路径和一个所有者(即拍摄照片的用户)。每个空间都有名字和文件路径。您能否设计一个可以容纳以下内容的REST系统:

  • 存储用户、照片和路径。
  • 访问空间和访问某个空间的某些照片。首先给出:
    1.我们想提出什么样的要求
    2.服务器应该返回什么响应
    3.每个响应的内容类型应该是什么

1.可能的解决方案-模型(POSSIBLE SOLUTION - MODELS)

1
2
3
4
5
6
7
{
“user”: {
"id": <Integer>,
“username”: <String>,
“password”: <String>
}
}
1
2
3
4
5
6
7
{
“photo”: {
"id": <Integer>,
“venue_id”: <Integer>,
“author_id”: <Integer>
}
}
1
2
3
4
5
6
7
{
“venue”: {
"id": <Integer>,
“name”: <String>,
“address”: <String>
}
}

2.可能的解决方案-请求/响应(POSSIBLE SOLUTION - REQUESTS/RESPONSES)

GET方式请求(GET REQUESTS)

Request- GET /index.html Accept: text/html Response- 200 (OK) Content-type: text/html

Request- GET /style.css Accept: text/css Response- 200 (OK) Content-type: text/css

Request- GET /venues Accept:application/json Response- 200 (OK) Content-type: application/json

Request- GET /venues/:id Accept: application/json Response- 200 (OK) Content-type: application/json

Request- GET /venues/:id/photos/:id Accept: application/json Response- 200 (OK) Content-type: image/png

POST方式请求(POST REQUESTS)

Request- POST /users Response- 201 (CREATED) Content-type: application/json

Request- POST /venues Response- 201 (CREATED) Content-type: application/json

Request- POST /venues/:id/photos Response- 201 (CREATED) Content-type: application/json

PUT方式请求(PUT REQUESTS)

Request- PUT /users/:id Response- 200 (OK)

Request- PUT /venues/:id Response- 200 (OK)

Request- PUT /venues/:id/photos/:id Response- 200 (OK)

DELETE方式请求(DELETE REQUESTS)

Request- DELETE /venues/:id Response- 204 (NO CONTENT)

Request- DELETE /venues/:id/photos/:id Response- 204 (NO CONTENT)

一起讨论学习

欢迎您一起学习和留言讨论RESTFUL,让我们一起写出真正的RESTFUL API。

dalaoyan wechat
扫一扫,用手机访问本站
-------------本文结束 感谢您的阅读-------------
作者dalaoyan
有问题请 留言 或者私信我的 微博
满分是10分的话,这篇文章你给几分