什么是 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第四单元暨课程总结

    第四单元架构设计总结 第一次作业 单独写了MyUmlClass.MyUmlInterface.MyUmlOperation三个类对应UML中相应元素,在UML图中这几个元素包含一些下级元素,如Clas ...

  2. 关于Green AI

    上一篇文章提到了模型不环保这个话题.这篇文章就这个问题展开唠叨一下. 自从BERT, GPT此类的大型模型诞生以来,小作坊们除了把pre-trained的模型拿过来微调一下,就束手无策了,因为成本实在 ...

  3. 后端Spring Boot+前端Android交互+MySQL增删查改

    2021.1.27 更新 已更新新版本博客,更新内容很多,因此新开了一篇博客,戳这里. 1 概述 使用spring boot作为后端框架与Android端配合mysql进行基本的交互,包含了最基本的增 ...

  4. 曾侯乙编钟引发的遐想之Java设计模式:状态模式

    目录 示例 简单例子 改进代码 状态模式 定义 意图 主要解决问题 何时使用 优缺点 曾侯乙编钟 状态模式-命令模式-策略模式 示例 一个类对外提供了多个行为,同时该类对象有多种状态,不同状态下对外的 ...

  5. 2021 年最值得推荐的 7 个 Angular 前端组件库 - DevUI

    摘要:DevUI 是一款面向企业中后台产品的开源前端解决方案,它倡导沉浸.灵活.至简的设计价值观,提倡设计者为真实的需求服务,为多数人的设计,拒绝哗众取宠.取悦眼球的设计.如果你正在开发 ToB 的工 ...

  6. OO博客总结——OO落下帷幕

    OO博客总结--OO落下帷幕 凡此过往,皆为序章. 不知不觉OO课程即将落下帷幕,一路坎坎坷坷磕磕绊绊,可算是要结束了,心里终于松了一口气,也有小小的不甘和遗憾.凡此过往,皆为序章.特殊的线上OO课程 ...

  7. 【新手指南】Android Studio中应用App的相关配置

    前言: 注意这是一个对于Android开发入门学习者而言的一个教程,因为自己平时很少使用Android进行原生应用的开发,对于使用Android Studio配置Android App应用的一些参数( ...

  8. Java基础(面试复习整理)

    基础知识和语法 Java语言初识 计算机语言发展 机器语言.汇编.C.C++.Java Java的诞生与发展 1995 JavaSE JavaME Android JavaEE 2006(大数据) H ...

  9. Python字体颜色设置

    Python字体颜色设置 平时学习工作中,我们经常会接触到一些大佬写的Python工具,运行起来总会显示出五颜六色的字体,比如红色代表Error , 黄色代表Warning , 绿色代表Success ...

  10. 反编译APP

    反编译APP 有两种反编译工具:dex2jar 和 apktool,两个工具反编译的效果是不一样的,dex2jar反编译出java源代码,apktool反编译出来的是java汇编代码. dex2jar ...