什么是 REST 架构风格

REST(Representational State Transfer)是表述性状态转移、分布式超媒体软件的一种架构风格,它基于使用 HTTP、URI 等现有的广泛流行的协议和标准,并由几个核心抽象概念支撑。

简单理解就是,REST 是一种 WEB 应用的架构风格,只要满足 REST 的约束和原则,就能够获得 REST 架构风格所带来的诸多优势。

资源

在REST架构中,“资源”扮演者主要角色。它具有以下特点:

资源是任何可以操作(获取、提交、更新、删除)的数据,比如一个文档(document)、一张图片……资源的集合也是一种资源,比如blogs表示博客(资源)的集合。

进行资源操作的时候,用 URI 来指定被操作的资源。如果一个 URI 不仅能标识一个网络上的资源,还能够定位这个资源,那么这个 URI 也叫 URL 。

表示

资源是一个抽象的概念,资源无法被传输,只能传输资源的表示。一个资源可以有多种表示,比如,一个资源可以用 HTML、XML、JSON 来表示。

具体传输哪种表示取决于服务端的能力和客户端的要求。传输的表示未必就是服务器存储时使用的表示,比如,这个资源在服务器不是以 HTML 或 XML 或JSON 来存储的,可能是一种更加利于压缩的表示。

总的来说,“表示”是“资源”的存储和传输形式,“资源”是“表示”的内容(抽象概念)。不管用什么形式来表示,始终描述的是这个资源。

无状态

根据 REST 的架构限制,RESTful 的服务器必须是无状态的,这意味着来自客户的每一个请求必须包含服务器处理该请求所需的所有信息, 服务器不能利用任何已经存储的“上下文(context,在这里表示用户的会话状态)”来处理新到来的请求,会话状态只能由客户端来保存,并且在请求时一并提供。

无状态让服务器系统的扩展性更强,很方便支持集群和分布式,不用考虑服务器之间的同步 session 状态问题,所以服务器之间的沟通开销很低。

这里注意两点:

  1. 服务器不能存储“上下文”不代表连数据库都不能有,“上下文”指那些在服务器内存中的、非持久化的数据。

  2. 无状态不代表不能有会话(sessions),无状态仅仅指服务器无状态。服务器不记录、维护会话,但是会话状态可以由客户端在每次请求的时候提供。

Token(令牌)认证机制

RESTful 提供的 API 是无状态的,即下一次调用请求与当前的调用请求时完全无关的,但这就无法保证系统资源的安全性。Token (令牌)认证机制就是用来解决无状态和安全性之间的矛盾。

其实现原理如下:

  • 用户发送用户名和密码(一般密码加密),请求验证通过;

  • 服务器判断用户名和密码是否正确

  • 服务器验证通过,返回Token及过期时间

  • 所有请求携带返回的Token在过期时间内即可通过Token验证并使用RESTful API(服务器验证Token时间过期,则无法正常使用RESTful API,需要重新请求验证)

REST 约束与风格

URI 标识资源

每个资源都应该是可标识的,都应该拥有一个明显的 ID。在 Web 中,代表 ID 的统一概念是:URI。URI构成了一个全局命名空间,使用URI标识你的关键资源意味着它们获得了一个唯一、全局的 ID。

操作资源

既然通过 URL 能够定位一个服务器上的资源。那么我们应该如何与这个资源进行互动呢?我们对这个资源 (URL) 使用不同的 HTTP 方法,就代表对这个资源的不同操作:

  • GET(SELECT):从服务器获取资源(一个资源或资源集合)。

  • POST(CREATE):在服务器新建一个资源(也可以用于更新资源)。

  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。

  • DELETE(DELETE):从服务器删除资源。

通过 HTTP 状态码表示操作的结果

200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。

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 - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

什么是 RESTful API

RESTful API 就是满足 REST 架构风格的 API,具体而言就是用 URI 定位资源、用 HTTP 标准方法(GET、POST、PUT、DELETE)描述操作,用响应状态码表示操作结果等。

RESTful API 有助于客户端和服务端的功能分离,服务器完全扮演着一个“资源服务商”的角色。各种不同的客户端都可以通过一致的 API 与这个“资源服务商”交流,从而与资源进行互动。

目前互联网公司越来越流行提供 RESTful API 形式服务供第三方调用。

如何设计 RESTful API

在过去不使用 RESTful 架构风格的时候,如果我们要设计一个系统,会以“操作”为出发点,然后围绕它去建设其他需要的东西。

举个例子,我们要向系统中增加一个用户登陆的功能:

  1. 需要一个用户登陆的功能(操作)

  2. 约定一个用于登录的API(也就是URL)

  3. 约定这个API的使用方式(发送响应什么数据、格式是什么)

  4. 前后端针对这个API进行开发

这种设计方式有如下缺点:

  1. 当我们不断为这个系统增加操作,每增加一个操作都要按照上面的流程设计一次,第 2 和 3 点的工作实际是可以大大削减的(通过 REST )。

  2. 操作之间可能是有依赖的,依赖多起来,系统会变得很复杂。

  3. 我们的 API 缺乏一致性(需要一份庞大的文档来记录 api 的地址、使用方式)。

  4. 操作通常被认为是有副作用(Side Effect)的,很难使用缓存技术。

而如果我们设计 REST 风格的系统,资源是第一位的考虑,首先从资源的角度进行系统的拆分、设计,而不是像以往一样以操作为角度来进行设计。

用两个例子来说明:银行的转账 API 和 即时通讯软件中发送消息的 API。

这两个功能非常具有“动作性”,看起来和“资源”联系不大,很容易就会设计成 not RESTful 的 API:POST /transfer/${amount}/to/${toUserID}、POST /api/sendMessage。

一旦在 URL 中引入了动词,这个URL的功能就定死了,无法用于别的用途(比如,GET /transfer/${amount}/to/${toUserID}或GET /api/sendMessage的语义很奇怪,不好使用)。并且,不同功能的API有各自的结构,一致性很差,需要一份详细的API文档才能使用。

这种情况下,要如何通过 RESTful 架构风格,设计一套一致、多用途的 URL 呢?

简单地说,就是将一个“动作”理解为“操作一个资源”。这里的“操作”是指HTTP的方法。

对于转账动作,就可以理解为“新建一个转账事务”(转账事务是资源),因此 API 就可以设置成这样: POST /transactions,请求体为:to=632&amount=500。这样的设计不但简洁明了,而且我们可以将这个URL用于别的用途:通过GET /transactions来获取该用户的所有转账事务。还可以将GET /transactions/456828定义为“获取某一次转账记录”。

即时通讯软件中发送消息的动作,我们可以理解为“操作聊天记录(聊天记录是资源,它是由“消息”组成的集合,消息也是资源)”,所以 API 设计为

POST /messages # 创建新的聊天记录(body传输消息的内容)

GET /messages # 获取聊天记录(返回一个数组,其中每个项是一个消息)

GET /messages/${messageID} # 获取某个消息的详细信息

PUT /messages/${messageID} # 更新某个消息(body传输消息的内容)

DELETE /messages/${messageID} # 删除某个消息的记录

从以上的两个例子我们可以看出,使用 RESTful 风格可以克服传统架构风格的 4 个缺陷:

  1. 设计API工作量减少,因为功能需求一旦出来,需要操作的资源、操作的方式立刻就能分析出来,因此资源URL和API的使用方式(GET, POST...)都很容易得到。

  2. 没有了操作之间的依赖。资源之间虽然可能有关联,但是小得多。

  3. 对资源的操作也就那么几种(获取、新建、修改、删除),API的一致性、自我描述性很强,不需要过多解释。

  4. 对于GET请求,我们都可以考虑使用缓存,因为在RESTful的架构中,GET请求代表获取数据,必须是安全、幂等的。

总结

REST 是一种软件架构风格,使用 REST 架构风格的软件架构具有很强的演化、拓展能力。

REST 架构风格详解的更多相关文章

  1. restful风格详解

    一.概念 RESTful架构,就是目前最流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所以正得到越来越多网站的采用. REST这个词,是Roy Thomas Fielding在他 ...

  2. Dubbo架构设计详解-转

    Dubbo架构设计详解  2013-09-03 21:26:59    Yanjun Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解 ...

  3. [CB]Intel 2018架构日详解:新CPU&新GPU齐公布 牙膏时代有望明年结束

    Intel 2018架构日详解:新CPU&新GPU齐公布 牙膏时代有望明年结束 北京时间12月12日晚,Intel在圣克拉拉举办了架构日活动.在五个小时的演讲中,Intel揭开了2021年CP ...

  4. Tomcat负载均衡、调优核心应用进阶学习笔记(一):tomcat文件目录、页面、架构组件详解、tomcat运行方式、组件介绍、tomcat管理

    文章目录 tomcat文件目录 bin conf lib logs temp webapps work 页面 架构组件详解 tomcat运行方式 组件介绍 tomcat管理 tomcat文件目录 ➜ ...

  5. dubbo初识(一)Dubbo架构设计详解

    参见http://shiyanjun.cn/archives/325.html Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合( ...

  6. Dubbo架构设计详解

    from:http://shiyanjun.cn/archives/325.html Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解 ...

  7. Dubbo架构设计详解(转自shiyanjun.cn)

    Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,Dubbo采用的是一种非常简单的模 ...

  8. MySQL 主从架构配置详解

    无论是哪一种数据库,数据的安全都是至关重要的,因此熟练掌握数据库的安全备份功能,是作为开发人员,特别是后端开发人员的一项必备技能.MySQL 数据库内建的复制功能,可以帮助我们对数据进行异地备份,读写 ...

  9. Dubbo架构设计详解--转载

    原文地址:http://shiyanjun.cn/archives/325.html Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解 ...

随机推荐

  1. OO 第二单元

    前言 ​ 第二单元 OO 作业的主题是多线程,课程组通过了电梯调度这个经典问题考察了多线程的调度. ​ 从第五次作业到第七次作业的迭代为,单部多线程可捎带电梯,多部多线程可捎带调度电梯(电梯属性相同) ...

  2. 如何用 Electron + WebRTC 开发一个跨平台的视频会议应用

    在搭建在线教育.医疗.视频会议等场景时,很多中小型公司常常面临 PC 客户端和 Web 端二选一的抉择.Electron 技术的出现解决了这一难题,只需前端开发就能完成一个跨平台的 PC 端应用.本文 ...

  3. sql 如何删除(代替)字段内某一部分内容

    方法一(此方法既可用于删除某一列字段中的某部分字符,也可用于替换某一列字段中的某部分字符) update Table_Name set Column_Name=replace(Column_Name, ...

  4. Typora配置PicGo时,提示Failed to fetch【Bug集中营】

    Typora配置PicGo时,提示Failed to fetch 两者配置的端口不一致造成的 打开Typora,选择文件-偏好设置-图像-验证图片上传选项,点击验证图片上传选项 会提示错误:Faile ...

  5. poj_3617 解题

    题意: 给定长度为N的字符串S,要构造一个长度为N的字符串T串. 从S的头部删除一个字符,加到T的尾部 从S的尾部删除一个字符,加到T的尾部 目标是构造字典序尽可能小的字符串. 示例输入: ACDBC ...

  6. 1149 Dangerous Goods Packaging

    When shipping goods with containers, we have to be careful not to pack some incompatible goods into ...

  7. ASP调用SDK微信分享好友、朋友圈

    ASP调用SDK微信分享好友.朋友圈需要用到sha1.asp,我先来上主代码,然后再附加sha1.asp,方便大家直接复制过去即可使用. 页面:shara.asp 1 <%@LANGUAGE=& ...

  8. 【vim】复制粘贴相关操作

    复制: 首先,可以在命令模式下输入v进入自由选取模式,选择需要剪切的文字后,按下d就可以进行剪切了. 其他命令模式下剪切命令: yy:复制当前行 nyy:n表示大于1的数字,复制n行 yw:从光标处复 ...

  9. Thinkphp5 日期与时间戳相互转换

    日期转换为时间戳 $date="2013-10-01 12:23:14"; dump(strtotime($date)); //=>1380601394 时间戳 转换为日期 ...

  10. Windows核心编程 第23章 结束处理程序

    第2 3章 结束处理程序 SEH(结构化异常处理) 使用 S E H的好处就是当你编写程序时,只需要关注程序要完成的任务. 如果在运行时发生什么错误,系统会发现并将发生的问题通知你.利用S E H,你 ...