什么是 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. 奇异值分解(SVD)与主成分分析(PCA)

    本文中的内容来自我的笔记.撰写过程中,参考了书籍<统计学习方法(第2版)>和一些网络资料. 第一部分复习一些前置知识,第二部分介绍奇异值分解(SVD),第三部分介绍主成分分析(PCA).以 ...

  2. 关于Vim/Neovim/SpaceVim的一些思考

    1 前言 最近看到了Neovim以及SpaceVim,于是上手试了一下. 2 Neovim与SpaceVim Neovim是Vim的一个分支,具有更加现代的GUI.嵌入式以及脚本化的终端.异步工作控制 ...

  3. JFX11+IDEA跨平台打包发布的完美解决办法

    1 概述 IDEA2020.1的文档中提到只有JFX8的工程才支持打成jar包,并且,如果直接使用Build Artifacts的话,会如下提示: IDEA文档有提到这个的解决办法,是使用一些第三方工 ...

  4. Appium 自动化测试框架:关键字驱动+数据驱动

    1. 关键字驱动框架简介 2. 框架结构说明 3. 框架代码实现 action 包  page_action.py business_process 包 case_process.py data_so ...

  5. 微服务的进程间通信(IPC)

    微服务的进程间通信(IPC) 目录 微服务的进程间通信(IPC) 术语 概述 通信视角 APIs 消息格式 RPC REST gRPC 断路器 API通信的健壮性 服务发现 异步消息 概念 消息 消息 ...

  6. 计算eks node 中pod数量

    计算eks node 中pod数量 计算公式:((IP数I - 1) * ENI数) + 2 实例规格等ENI数和IP的对应关系,请参考 https://docs.aws.amazon.com/zh_ ...

  7. 2021S软件工程——个人阅读作业2

    2021S软件工程--个人阅读作业2 项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任建) 这个作业的要求在哪里 个人阅读作业#2 我在这个课程的目标是 了解并熟悉软件开发的具体流程, ...

  8. Python第一章-基础知识

    第一章:基础知识 1.1 安装python.     直接官网下载最新的python然后默认安装就可以了,然后开始菜单里找到pyhton *.*.* Shell.exe运行python的交互shell ...

  9. Python 爬虫之Scrapy框架

    Scrapy框架架构 Scrapy框架介绍: 写一个爬虫,需要做很多的事情.比如:发送网络请求.数据解析.数据存储.反反爬虫机制(更换ip代理.设置请求头等).异步请求等.这些工作如果每次都要自己从零 ...

  10. Win64 驱动内核编程-14.回调监控文件

    回调监控文件 使用 ObRegisterCallbacks 实现保护进程,其实稍微 PATCH 下内核,这个函数还能实现文件操作监视.但可惜只能在 WIN7X64 上用.因为在 WIN7X64 上 P ...