普里亚普斯 学习站

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1868 | 回复: 8

第 01 章 什么是REST?

 关闭 [复制链接]

15

主题

76

回帖

1138

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1138
发表于 2021-8-27 23:18:55 | 显示全部楼层 |阅读模式
REST,全称为REpresentational State Transfer,即表述性状态传递

是一种应用程序的架构风格,用于构造简单、可靠、高性能的Web应用程序。

REST提出了一系列约束,遵循这些约束的应用程序称为RESTful API应用。

通常情况下,REST是基于HTTP协议而实现的。

API
应用程序编程接口,用来“连接”两个不同的系统,并使其中一方为另一方提供服务,如在操作系统上运行的应用程序能够访问操作系统所提供的API,并通过这些API来调用操作系统的各种功能。

即:API是一个系统向外暴露或公开的一套接口,通过这些接口,外部应用程序能够访问该系统。


REST
表述性状态传递。是一种软件架构风格。作为一种Web服务的设计与开发方式,REST可以降低开发的复杂性,提高系统的可伸缩性。

REST是一种基于资源的架构风格,在REST中,资源(Resource)是最基本的概念。任何能够命名的对象都是一个资源,如:document、user、order等,通常情况下,它表示Web服务中要操作的一个实体。

一个资源具有一个统一的资源标识符(Uniform Resource Identifier,URI),如users/1234,通过资源标识符能够标识并访问该资源。

除了单个的资源外,资源集合表示多个相同类型的资源,如users。

在系统设计时,不同的实体之间往往存在某种关联关系,如一个用户有多个订单。同样,在REST中,这种关联关系也能够由资源之间的层次关系体现出来,如users/1234/orders/1。

由于REST以资源为中心,因此REST接口的端点(Endpoint)均以资源或资源集合结尾,它不像其他形式的Web服务一样以动词结尾,如api/GetUserInfo或api/UpdateUserInfo。在REST中,对资源的动作或操作是通过HTTP方法来完成的,如下:

[mw_shl_code=text,false]GET api.domain.com/users/1234
PUT api.domain.com/users/1234[/mw_shl_code]
  • GET:获取
  • PUT:更新

当请求方发起请求,修改了资源的状态后,更新后的资源表述应返回给请求方,这也是表述性状态传递的意义。

REST 约束
6个REST的约束(Constraint),遵循这些约束的WEB服务才是真正的RESTful服务,即:REST风格的服务。违反其中一个都不算。

(1)客户端-服务器(Client-Server)
客户端-服务器约束体现了关注点分离(Separation of Concerns)原则,使客户端与服务端各自能够独立实现并独立开发,只要它们之间的接口不改变即可;
客户端与服务端可以使用不同的技术或编程语言。


(2)统一接口(Uniform Interface)
统一接口是设计任何RESTful服务的基础,也是区别REST架构风格与其他Web服务风格的最主要约束。系统中的多个组件(包括服务端、客户端,以及可能存在的代理服务器等)都依赖于统一接口。
统一接口约束本身又由4个子约束组成,分别如下。

资源的标识
前面提到过,任何能够命名的对象都是一个资源,资源能够通过统一资源标识符来区别。对于Web系统,统一资源标识符通常是一个URL,即统一资源定位符(Uniform Resource Locator)。每个URL代表一个资源或资源集合,当访问一个URL时,能够获取该资源或对它执行相应的操作。

通过表述操作资源
当请求一个资源时,服务器返回该资源的一个表述。该表述表示资源当前的状态,它由表述正文和表述元数据组成,格式通常为JSON、XML和HTML等,比如以下代码是同一资源的两种不同的表述形式。
[mw_shl_code=json,false]{
  "User": {
    "id": "123",
    "name": "Tom"
  }
}[/mw_shl_code]

[mw_shl_code=xml,false]<User>
    <id>1234</id>
    <name>Tom</name>
</User>[/mw_shl_code]
客户端在请求资源时,能够指定期望的表述格式,服务器在返回响应时,在响应中包含了指定表述格式的资源;
访问同一个资源的不同格式无须修改资源的标识符,客户端也可以通过资源的表述(而非资源本身)对资源进行操作。

自描述消息
客户端与服务器之间传递的每一条消息都应包含足够的信息,这些信息不仅包含了资源的表述,也包含了资源表述的相关信息(如资源表述的格式与内容长度等),甚至包含了与该资源相关的其他操作信息。

超媒体作为应用程序状态引擎(HATEOAS)
服务器返回的资源表述中不仅要包含资源的表述,也应包含与之相关的链接,这些链接能够对资源执行其他操作,比如当获取资源时,返回的链接中包含更新该资源、删除该资源等链接。

(3)分层系统(Layered System)
分层系统约束能够使网络中介(如代理或网关等)透明地部署到客户端与服务器之间,只要它们遵循并且使用前面提到的统一接口约束即可;而客户端和服务端则都不知道网络中介的存在。中间服务器主要用于增强安全、负载均衡和响应缓存等目的。

(4)缓存(Cache)
缓存是Web架构中最重构的特性之一。客户端或网络中介均能够缓存服务器返回的响应,因此当服务器返回响应时,应指明该响应的缓存特性。对响应进行缓存将有助于减少数据获取延迟以及对服务器的请求,从而提高系统的性能。

(5)无状态(Stateless)
无状态约束,指明服务器不会记录或存储客户端的状态信息,反之,这些状态信息应由客户端来保存并维护,因此客户端对服务器的请求不能依赖于已发生过的其他请求,当客户端请求服务器时,必须在请求消息中包含所有与之相关的信息(如认证信息等)。

(6)按需编码(Code-On-Demand)
按需编码约束允许服务器临时向客户端返回可执行的程序代码(如脚本等),返回这些代码主要用于为客户端提供扩展性或自定义的功能。由于客户端必须理解并能够执行服务器返回的代码,因此这一约束增加了客户端与服务器之间的耦合,同时,这一约束是可选的。

REST的错误理解
深入的理解REST,有助于我们设计RESTful服务和RESTful API。

错误的认知包含:
  • 任何使用了HTTP方法的API。
  • 返回JSON的API。
  • 执行增删查改的API。

REST风格的API虽然有删除特点,但是并不是说具有上述特点的API就是RESTful API。

Richardson成熟度模型是衡量API成熟度的一种方式,该模型进一步描述了各种Web API的特征,根据该模型,只有最成熟的API才是RESTful API。

REST外的另一种API风格:RPC风格(即:远程过程调用,Remote Procedure Call),如下:
[mw_shl_code=text,false]GET api.domain.com/getUserInfo
GET api.domain.com/UpdateUserInfo[/mw_shl_code]
REST风格 和 RPC 风格 的区别如下:
  • 在关注点方面,REST面向资源,RPC面向功能。
  • 在API端点方面,REST的端点是名词、是资源或资源集合,而RPC的端点是动词、是方法名。
  • 在执行特点方面,REST对资源执行操作,RPC执行服务器上的方法。
  • 在返回结果方面,REST返回请求的资源,而RPC则返回调用方法的执行结果。




HTTP协议

REST是基于HTTP协议而实现的。

HTTP,超文本传输(Hyper Text Transfer Protocol,HTTP)协议,广泛的网络协议,基于 TCP/IP 协议的应用层协议。



当客户端(通常是浏览器)发起一个HTTP请求时,它首先会建立起到HTTP服务器指定端口(HTTP协议默认使用80端口)的TCP连接,而HTTP服务器则负责在该端口监听来自客户端的请求。当TCP连接成功建立后,浏览器就会向HTTP服务器发送请求命令,如GET /index.html HTTP/1.1。一旦收到请求,服务器会根据请求向客户端返回响应,其响应内容通常包括一个状态行(如HTTP/1.1200 OK)和若干个消息头,以及消息正文。消息正文则是资源、请求的文件、错误或者其他信息等。

HTTP 是明文传输的,不安全,1994年设计了HTTPS协议,即超文本传输安全协议(Hypertext Transfer Protocol Secure),也被称为HTTP over TLS,HTTP over SSL。

统一资源定位符

即通常所说的URL,代表网络上一个特定的资源。URL作为URI的子集,一个URL就是一个URI,用于标识并定位资源。

对于HTTP而言,当用户在浏览器中输入了一个URL后,意味着他想要获取或查看一些资源。

URL由以下部分组成:
  • http:// ,URL协议,指明了如何访问一个特定的资源,http:// 会告诉浏览器要使用HTTP协议,即超文本传输协议;除 http:// 外,较为常见的协议还有 https:// (加密的HTTP协议)、ftp:// (文件传输协议)和 mailto: (电子邮件协议)等。
  • www.….com,主机名,告诉浏览器要访问的资源所在的服务器名称。DNS(Domain Name System)服务器会将这个名称解析为一个具体的IP地址,通过这个IP地址可以找到资源所在的计算机。
  • /images/logo.png,URL路径(Path),它指向服务器上具体的资源。根据要获取资源的不同,其值也会不同,可以说,这一部分的变化性最大。它有可能是在服务器的一个真实存在的文件,比如这里的/images/logo.png,也有可能是由常见的Web框架生成的动态资源,如http://www.….com/account/index。通常情况下,当访问某个网页资源时,浏览器会下载其他与此相关的资源,例如http://www.….com这个网页,它不仅包括文本信息,也包括图片、JavaScript文件、CSS以及其他资源,所有这些资源构成了我们在浏览器中看到的页面。

除了上面,还有:
  • 端口号,在主机名后面,以冒号隔开。HTTP协议默认使用80端口(默认,一般忽略),如果URL中省略了端口号,则默认使用此端口;如果HTTP服务器并没有在80端口监听,而使用了其他端口,则需要在URL中指定端口号,如http://www.…. com:8080,但这种情况比较少见,通常在开发或调试Web应用时才会使用其他端口。
  • 查询字符串,URL中“?”后面的参数部分,对于 http://www.….com/search?q=hello 这样一个URL,“q=hello”即为查询字符串,其中“q”是参数名,“hello”是参数值,参数名和参数值用“=”分隔。如果要传递多个参数,则使用“&”来分隔,如name1=value1&name2=value2。查询的字符串会发送给HTTP服务器,并由服务器上的Web应用程序决定如何处理这一部分的内容。
  • 锚部分,也称片段(Fragment),即在“#”后面的内容,它用于指明一个资源的特定位置,例如,http://www.….com/index.html#contact,该URL将定位到HTML页面中指定的元素。这一部分内容与上述其他部分都不一样,它不会由服务器处理,只会由浏览器来处理,也就是说,若更改这一部分的内容,并不会向服务器再次发起请求,浏览器就会定位到当前资源的不同位置。

媒体类型

响应中指明资源的内容类型(Content-Type),也称媒体类型。要指定内容类型,HTTP依赖于MIME标准。

MIME(Multipurpose Internet Mail Extensions),即多用途互联网邮件扩展类型,是一种表示文档的性质和格式的标准,因此,媒体类型也被称为MIME类型。

浏览器通过MIME类型来决定如何处理文档,因此服务器在返回响应时为资源设置正确的MIME类型非常重要。

HTTP服务器会返回HTML内容,并标识其内容类型为text/html。text为主类型,后一部分html则是子类型。

而当请求一个图片资源时,根据图片文件本身的格式,HTTP服务器将返回资源的媒体类型标记为image/jpeg或image/gif。

MIME的组成结构非常简单,其语法为type/subtype,它由类型与子类型两个字符串构成,中间用“/”分隔,不允许空格存在。对大小写不敏感,但传统写法都是小写的。



常见的:text/plain: text/html: image/jpeg: image/png: application/json

HTTP消息

HTTP请求和响应消息包括以下4部分的内容:
  • 起始行:即第一行,用于描述要执行的请求,或者是对应的状态,即成功或失败,这个起始行总是单行的。
  • HTTP消息头:这些消息头描述了请求或响应的相关属性、配置、对消息正文的描述等。
  • 空行:指明消息头已经发送完毕。
  • 消息正文:包含请求数据(如要创建的资源、HTML表单内容等),或响应中资源的表述,这一部分可以为空。

请求:
[mw_shl_code=text,false]GET / HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134
Accept-Language: zh-CN
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Upgrade-Insecure-Requests: 1
Accept-Encoding: gzip, deflate
Host: microsoft.com
Connection: Keep-Alive[/mw_shl_code]
响应:
[mw_shl_code=text,false]HTTP/1.1 200 OK
Date: Mon, 27 Jul2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain[/mw_shl_code]

并不是所有的 请求/响应 都有正文,比如获取资源(GET)、获取资源元数据(HEAD),以及删除资源(DELETE)等请求,通常它们不需要正文,而那些要将数据从客户端发送到服务器的HTTP方法,它们若要创建资源或更新资源,就需要提供正文,比如POST和PUT等。

HTTP 方法告诉服务器当前请求要执行哪一种操作。常见的HTTP方法有GET、POST、PUT、DELETE、PATCH、HEAD和OPTIONS等。

GET:获取指定的资源,它并不会修改资源,因此GET方法是安全的。此外,GET方法也是幂等的。

  • 所谓安全方法,是指不会修改资源的方法。
  • 所谓幂等,是指多次对同一个URL调用同一个HTTP方法,其效果总是一样的。

POST:创建资源。不是安全方法,因为它会修改服务器上的资源;也不是幂等方法,多次请求同一个POST操作会产生多个不同的资源。

PUT:更新资源,因为PUT会修改资源,所以它不是安全的方法。与POST方法不同的是,PUT方法是幂等的,多次更新同一个资源,其返回结果都是一样的。
PUT方法除了更新资源外,当资源不存在时,它还可以创建资源。

注意,尽管POST与PUT方法都可以创建资源,但它们所请求的URI是有区别的,POST请求的URI是资源集合,而PUT则是请求单个不存在的资源,例如:
[mw_shl_code=text,false]POST api.appdomain.com/users
PUT api.appdomain.com/users/1234[/mw_shl_code]
DELETE:删除资源,它不是安全的,但它是幂等的,这意味着对同一资源请求多次DELETE方法,效果都是一样的。当第一次对资源调用DELETE方法时,返回表示操作成功的200 OK状态码,后续再调用DELETE方法,由于资源已经不存在,则应返回404 Not Found状态码。

PATCH:对资源进行部分更新,它与PUT方法的区别是:PUT会更新指定资源的全部内容,而PATCH可以根据需要仅更新资源的部分字段或属性。

HEAD:与GET方法相同,但它并不返回消息正文,在响应消息中仅包含响应状态码与消息头,该方法常用来检测资源是否存在以及获取资源的元数据。

OPTIONS:获取资源支持的操作,服务器在返回的响应中会包含Allow消息头,它的值为HTTP方法列表,例如:
[mw_shl_code=text,false]Allow: GET, POST[/mw_shl_code]


HTTP消息头
用来传递附加信息。一个消息头由消息头名称和它的值组成,中间用冒号“:”隔开,比如 Content-Type: text/plain。

常见请求头:


常见响应头:


自定义消息头,用于返回一些描述或备注类的信息。自定义消息头的名称一般以“X-”开头,以此来指明它并不是一个标准的HTTP消息头,例如X-AspNet-Version用于指明当前服务器运行的ASP.NET的版本。


状态码
由3个数字组成,用于指明HTTP请求的结果。

状态码可分为以下5类。
  • 1xx:信息,服务器收到请求,需要请求方继续执行操作。
  • 2xx:成功,服务器成功执行客户端所请求的操作。
  • 3xx:重定向,需要进一步的操作以完成请求。
  • 4xx:客户端错误,请求包含语法错误或请求内容不正确。
  • 5xx:服务端错误,服务器在处理请求的过程中发生了错误。

状态码以其首位数字表示它所属的类别,而后两位则表示在该类别中具体的信息,常见状态码:





REST 的最佳实践
REST 是一种架构风格,不是标准,也就没有一套确定的、 公认的规则。
虽然有6种约束,但具体实践项目实现时,在很多细节上仍有多种多样的方式。

首先,在实现RESTful系统时,应正确地使用HTTP方法、HTTP消息头和HTTP状态码。

比如:
  • 对于 HTTP 方法,应使用GET方法获取资源,使用POST方法创建资源。
  • 对于 HTTP 消息头,当客户端要想指定资源的预期表述格式时,应使用Accept消息头,而非其他方式,这也正是该消息头的意义所在。
  • 对于 HTTP 状态码,当操作成功却不需要返回响应正文时,应使用返回204 No Content(删除或更新资源)或201 Created(创建资源)。又如,当服务器不支持客户端指定的资源表述格式时,应返回406 Not Acceptable状态码。

除了这些原则以外,在设计资源的URI时也应注意下列原则:

使用名词的复数表示一个资源集合,如 api.domain.com/users

使用斜线“/”用来表示资源之间的层次关系,如 api.domain.com/users/1234/orders

对资源的增、删、查、改等操作名称不应包含在URL中,反之应正确使用HTTP方法。比如,GET /deleteuser/1234(错误),DELETE users/1234(正确)。

如果一个操作无法对应到资源的某个操作上,此时可以适当地在URI中包含动词,但仍然应该基于一个资源的标识符,如下所示。
[mw_shl_code=text,false]PUT /users/1234/set-admin
DELETE /users/1234/set-admin[/mw_shl_code]
查询字符串可以用来对资源进行筛选、搜索或分页查询等操作,如:
[mw_shl_code=text,false]GET /users?role=admin
GET /users?searchQuery=abc
GET /users?pageSize=25&pageNumber=2[/mw_shl_code]
URI应使用小写字母。

URI中可以使用中划线“-”来增加其可读性,使用“-”来代替空格,如:
[mw_shl_code=text,false] api.domain.com/blogs/this-is-my-first-post[/mw_shl_code]
URI中不应使用下划线。在浏览器或高级编辑器中,URI通常会带有下划线,以表示它是可点击的,这个下划线将会使URI中的下划线不可见,可以使用中划线“-”替代下划线。

URL末尾不应包含斜线“/”,尽管URL末尾包含了“/”并不影响其功能,然而末尾的“/”没有任何意义甚至还有可能会造成歧义,因此服务器返回给客户端的URL末尾不应包含“/”。

其他问题
在RESTful API中,JSON和XML是最常用到的两种资源表述格式,它们都可以用来传递数据,且都具有简洁、自描述等特点。

JSON的MIME类型为aplication/json。

JSON 的数据使用 名称/值 来表示,名称/值 包括字段名称和它的值,中间用冒号隔开。其中字段名称应使用双引号表示,字段的值如果是字符串,也应使用双引号表示,如"firstName" : "John"。

JSON数据项的值的类型可以是下列类型。
  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true或false)
  • 数组(在方括号中)
  • 对象(在花括号中)
  • null

对象,在大括号{}中书写,包含多个名称/值对:
[mw_shl_code=json,false]{
  "id": "1234",
  "name": "Tom"
}[/mw_shl_code]
数组,多个相同的数据项构成,用方括号[]表示:
[mw_shl_code=json,false]{
  "users": [
    {
      "id": "1234",
      "name": "Tom"
    },
    {
      "id": "1235",
      "name": "Smith"
    }
  ]
}[/mw_shl_code]
XML是可扩展标记语言,必须包含根元素,该元素是文档中其他元素的父元素。文档中的所有元素形成了一棵文档树,这棵树从根部开始,并扩展到树的最底端。
标签名区分大小写!
标签允许包含一个或多个属性,每个属性的值必须使用引号。
[mw_shl_code=xml,false]<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>[/mw_shl_code]


API 版本
当API发生了变化,如:资源表述内容有新增项(字段或属性)或系统添加了新资源类型时,应使用不同的版本来区别对API的更改

RESTful API添加版本有以下4种方式。
  • 使用URI路径,如 api/v1/users。
  • 使用查询字符串,如 api/users?version=v1。
  • 使用自定义消息头,如 Accept-version: v1。
  • 使用Accept消息头,如 Accept: application/json;v=2.0。


本章完

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0

主题

4

回帖

8

积分

新手上路

Rank: 1

积分
8
发表于 2022-9-15 10:30:16 | 显示全部楼层
牛掰~
回复

使用道具 举报

0

主题

5

回帖

10

积分

新手上路

Rank: 1

积分
10
发表于 2022-10-8 10:51:31 | 显示全部楼层
回复

使用道具 举报

2

主题

73

回帖

210

积分

中级会员

Rank: 3Rank: 3

积分
210
发表于 2023-5-19 08:49:23 | 显示全部楼层
对楼主的崇拜如洪水滔滔
回复

使用道具 举报

15

主题

76

回帖

1138

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1138
 楼主| 发表于 2023-5-19 21:51:10 | 显示全部楼层
admin,你是天使请来的都比吗?
回复

使用道具 举报

0

主题

50

回帖

70

积分

注册会员

Rank: 2

积分
70
发表于 2023-5-27 15:37:43 | 显示全部楼层
不错的帖子
回复

使用道具 举报

0

主题

52

回帖

72

积分

注册会员

Rank: 2

积分
72
发表于 2023-6-7 23:36:17 | 显示全部楼层
楼主admin是我最佩服的人!
回复

使用道具 举报

2

主题

73

回帖

210

积分

中级会员

Rank: 3Rank: 3

积分
210
发表于 2023-6-8 20:59:42 | 显示全部楼层
厉害啊
回复

使用道具 举报

2

主题

73

回帖

210

积分

中级会员

Rank: 3Rank: 3

积分
210
发表于 2023-7-3 15:28:25 | 显示全部楼层
给力啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋

GMT+8, 2024-5-15 09:51 Processed in 0.040237 second(s), 30 queries .

© 2024 普里亚普斯 学习站 Powered by Discuz! X3.4 Licensed Theme by Jvmao 粤ICP备19010473号

快速回复 返回顶部 返回列表