RESTful API

什么是restful

REST,即Representational State Transfer的缩写。直接翻译的意思是"表现层状态转化"。
(1)、REST指的是一组架构约束条件与原则。“如果一个架构符合REST的约束和原则”,我们就称它为RESTful架构。
(2)、Representation State Transger有人翻译为表征状态转移,也有人翻译为表述性状态转移,也有人翻译为表现层状态转移,也有人翻译为"呈现状态转移"。我的理解是"表征状态转移"。
(3)、REST本身并没有创建新的技术、组件或服务,而隐藏在RESTful背后的理念就是使用Web的现有特征和能力,更好地使用现有Web标准中的一些准则和约束。虽然REST本身收Web技术的影响很深,但是理论上REST架构风格并不是绑定在HTTP上,只不过目前HTTP的唯一与REST相关的实例。所以我们这里描述的REST也是通过HTTP实现的REST。

产生背景

近年来移动互联网的发展,前端设备层出不穷(手机、平板、桌面电脑、其他专用设备…),因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信,于是RESTful诞生了,它可以通过一套统一的接口为 Web,iOS和Android提供服务。
在这里插入图片描述

URI

即统一资源标识符,服务器上每一种资源,比如文档、图像、视频片段、程序 都由一个通用资源标识符(Uniform Resource Identifier, 简称"URI")进行定位。

HTTP动词

常用的HTTP动词有下面五个

  • GET(SELECT):从服务器取出资源(一项或多项)。
  • POST(CREATE):在服务器新建一个资源。
  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
  • DELETE(DELETE):从服务器删除资源。
RESTful架构

服务器上每一种资源,比如一个文件,一张图片,一部电影,都有对应的url地址,如果我们的客户端需要对服务器上的这个资源进行操作,就需要通过http协议执行相应的动作来操作它,比如进行获取,更新,删除。

简单来说就是url地址中只包含名词表示资源,使用http动词表示动作进行操作资源
举个例子:左边是错误的设计,而右边是正确的

GET /blog/getArticles --> GET /blog/Articles  获取所有文章
GET /blog/addArticles --> POST /blog/Articles  添加一篇文章
GET /blog/editArticles --> PUT /blog/Articles  修改一篇文章 
GET /rest/api/deleteArticles?id=1 --> DELETE /blog/Articles/1  删除一篇文章

REST关键原则

由于REST定义了应该如何正确的使用Web标准,例如HTTP和URI。如果你在设计应用程序的时能坚持REST原则,那就预示着你将会得到了一个优质的Web架构。REST有5条关键原则如下:

  • 1.为所有“事物”定义ID
  • 2.将所有事物链接在一起
  • 3.使用标准方法
  • 4.资源多重表述
  • 5.无状态通信

下面让我们来详细解析一下:

1、为所有"事物"

这里我使用了"事物"来代替更准确的术语"资源"。大家可以想一下人们构建的系统,通常会找到一系列的值来标识关键的抽象,就像数据库中的"表"里面的"主键"一样,那么在web的世界里面是什么那?大家答对了,就是URI,RUI构成了一个全局命名的空间。使用URI来标识你的关键资源意味着它们获得了一个全局的、唯一的ID。
记得之前看过一本书叫,里面阐述了一种思想,就是尽量使用那些能够被绝大多数人所能理解的规则,这样你做的任何东西对别人来说是没有学习成本的。同样的道理,如果在你的application里面定义一个对默写事务的抽象,别人能瞬间理解(比如消费者,应该定义为consumer)。更加直观的讲,在淘宝上每一个商品都有他的一个固定的ID(URI)。否则,那就扎心了,老铁。
当这样设计的时候,很多人会怀疑这样是否会直接向外面暴露你的数据库记录。但是其实它和隐藏现实细节之间没有任何冲突,通常值得被URI标识的事物——资源——要比数据库记录要抽象的多。例如,一个订单资源可以由订单项,地址以及其他方面组成。标识所有值的标识事物,领会这一个观念可以引导你创建出在传统应用程序中不常见的资源。一个流程,一个谈判,一次饭局,这都是应该标识的事务的示例。
下面是一些你可能想到的URI的例子:

http://example.com/customers/1234
http://example.com/orders/2007/10/776654
http://example.com/products/4554
http://example.com/processes/salary-increase-234

基于我创建了便于阅读的URI——这个有用的观点,尽管不是RESTful设计所必须的,但是你们应该会十分容易的推测出 URI的含义:他们明显的"标识"某一数据的数据项。
继续往下看

http://example.com/orders/2007/11
http://example.com/products?color=green
大家看到这两个URI看起来和之前有些不同,因为它们不是对一件事物的标识,而是对一类事物的标识(假设第一个URI标识了所有2007年11月份的订单,第二个标识了绿色产品的集合)。但是这些集合自己也是事物(资源),也应该被标识。

PS:使用全局、唯一的命名规则的好处,既适用于浏览器中的Web应用,也适用于当前的移动互联网中的app应用。
最后总结一下:使用URI标识所有值得标识的事务,特别是应用中提供的所有"高级"资源,无论这些资源代表单一数据、数据项集合、虚拟亦或实际的对象还是计算结果等。

2、将所有事务连接在一起

这里说的是“链接”的思想,链接在我们HTTP中是非常常见的概念。但是他的用处应该不止于此,比如下面的json

{"url":"https://www.hao123.com/"}

但你看见上面的链接,应用程序可以通过检索json,跟踪链接获取更多的信息。使用URI表示链接的优雅之处在于,链接可以指向不同应用、不同服务器甚至位于南极洲的服务器。因为URI命名规范是全球标准,构成WEB的所有资源都可以互联互通。
链接的原则还有一个更重要的方面——应用"状态"。简而言之,实际上服务器端为客户端提供一组链接,使客户端能通过连接将应用从一个状态改变为另一个状态。稍后我们会在另一篇文章探究这个方面的影响;目前,只需要记住链接是构成动态应用的有效方式。
总结一下:任何可能的情况下,使用链接指引可以被标示的资源。也正是链接造就了现在的Web。

3、使用标准方法

当你在浏览器里面输入一个uri的时候,浏览器就会跳转你制定的地址。但是你的浏览器是怎么知道该如何操作的那?那是因为浏览器知道所有的资源(uri)都支持同样的接口。一套同样的方法,如下图所示

在这里插入图片描述
其中HEAD,TRACE,OPTIONS,CONNECT 在RESTful API 设计中不常用,这些Methods具体定义可以在
其中 HEAD,TRACE,OPTIONS,CONNECT 在 RESTful API 设计中不常用,这些 Methods 具体定义可以在这里找到。如果需要,可以根据相关语意来实现具有对应功能的API。
如果你采用RESTful的方式暴露应用功能,那这条原则和它同样也适用于你。
为什么使用标准方法如此重要?从根本上说,它使你的应用称为Web的一部分——应用程序为Web变成Internet上最成功的应用所做的贡献,与它添加到Web中的资源数量成比例。采用RESTful方式,一个应用可能会向Web中添加数以百万计的客户uri。
统一接口也使用所有理解HTTP应用协议的组件能与你的应用交互。通用客户程序就(generic client)是从从收益的例子,比代理,缓存,网关等。
总结一下:为了使客户端程序能与你的资源相互协作,资源应该正确地实现默认的HTTP协议(HTTP),也就是使用标准的GET/PUT/POST/DELETE方法。

4、资源多重表述

到目前为止我们忽略了一个复杂的问题:客户端程序如何知道怎么处理检索的导数据,比如GET或者POST请求的结果?其实HTTP采取的方式是允许数据处理和操作调用之间的关系分离的。换句话说,如果客户程序知道如何处理一种特定的数据格式,那就可以与所有提供这种格式的资源交互。让我们再用一个例子来阐述这个观点,利用HTTP内容协商(content negotiation),客户端程序可以请求一种特定格式的表述:

GET /customers/1234 HTTP/1.1
Host: example.com 
Accept: application/vnd.mycompany.customer+xml  

响应的返回值可能是一些公司专有的XML格式表述的客户信息。
假设客户端发起的请求是另外一个不同的请求,如下:

GET /customers/1234 HTTP/1.1
Host: example.com 
Accept: text/json

响应的返回值就可能是json格式的
这说明为什么理想的情况下,资源表述应该采用标准格式,如果客户端对HTTP应用协议和数据格式都有所"了解"。那么它就可以用一种有意义的方式与世界上任意一个RESTful HTTP应用交互。
在实际应用中,资源多重表述还有其他的好处:如果你为你的资源提供HTML和XML两种表述方式,那这些资源不仅可以被你的应用所用,还可以被任意标准Web浏览器所用。你的应用信息可以被所有会使用Web的人获取到。
总结:针对不同的需求提供资源多重表述。

五、无状态通信

所谓无状态通信,即所有的资源,都可以通过URI定位,而且这个定位与其他资源无关,也不会因为其他资源的变化而改变。有状态和无状态的区别,举个例子说明下。例如查询某员工的工资,以为查询工资是需要登录系统,进入查询工资的页面,执行相关操作后,获取工资的信息,则这种情况吸是有状态的,因为查询征信的每一步操作都依赖于前一步的操作,只要前置操作不成功,后续操作就无法执行;如果输入一个URI即可得到指定某人的工资,则这种情况是无状态的,因为获取工资的信息是不依赖其他资源或者状态,且这种情况下,某人的工资信息是一个资源,由一个URI与之相对应,可以通过HTTP中的GET方法获取资源,这就是典型的RESTful风格。

在这里插入图片描述
在这里插入图片描述

五、ROS、SOA、REST与RPC

ROA即Resource Oriented Architecture,RESTful架构风格的服务是围绕资源展开的,是典型的ROA架构,虽然ROA与SOA并不冲突,甚至把ROA看做SOA的一种未尝不可。因此RESful架构风格的服务通常被称之为ROA架构,很少提及SOA架构,以便更加显示的与RPC区分。
PRC风格曾是WebService的主流,最初是基于XML-PRC协议,后来渐渐被SOAP协议取代;但是RPC的风格不仅仅可以用HTTP,还可以用TCP或者其他通信协议。但是PRC风格的服务,受服务器采用语言的束缚比较大。进入移动互联网时代后,RPC风格的服务很难在移动端使用,而RESTful风格的服务,由于可以直接以json为载体承载数据,以HTTP方法为统一接口完成数据操作,客户端的开发部依赖于服务实现的技术,移动端也可以轻松使用服务,这也加剧了REST取代RPC称为Web Service的主导
RPC与RESTful的区别如下面两个图所示

在这里插入图片描述
在这里插入图片描述

六、总结

最后我们从REST的名字来重新分析并总结一下REST。
REST的全拼是(Respresentational State Transfer) 其中Respresentational指的是资源即Resource 而State Transfer 是状态转化,那么我从这两个方面来重新解读一下

1、资源(Resources)是REST的核心

REST开发又被称作“面向资源的开发”,这说明对于资源的抽象是设计RESTful API的核心内容。RESTful API建模的过程与面向对象建模类似,是以名词为核心的。这些名词就是资源,任何可命名的抽象概念都可以定义为一个资源。对于业务的抽象是设计一套好的RESTful API的基础,这就好比建房子打地基,如果地基没有打好,后面建的楼就很容易歪掉,其美观度,可维护性,可扩展性就会大大折扣。我会建议在设计初期一定要在资源的定义上多花功夫,抽象出适合业务发展的资源。也就是说一开始要把产品的RESTful风格定义下来,后面的扩展都可以基于这样的风格延续下去。
下面是几条小的建议:

  • 理清资源的层次结构,比如业务针对的范围是养鸡场,那么学校会是一级资源(/school),老师(/school/teachers),学生(school/students)就是二级资源。
  • 资源尽量用准备的英文名词去表达,资源组都是用复数来表示。一个号的资源定义一定是不需要解释的。
2、资源的状态转化(State Transfer)

访问一个网站或者接口,就代表客户端和服务器一次交互的过程,而这个过程势必会涉及到数据和状态的变化。而HTTP协议又是无状态的,这就意味着所有的状态都保存在服务器。如果某个客户端想要做操作服务器必须通过某种手段让服务器发生状态转换,那么客户端就可以操作资源,而资源的状态转化就转化为对资源的各种操纵。而这些操作通常是通过HTTP协议的四种方法来实现的GET/POST/PUT/DELETE。还有其他不常用的方法PATCH/HEAD/OPTIONS。

最后再次重申RESTful 是风格,不是标准。

作者:隔壁老李头
链接:https://www.jianshu.com/p/52f3ca09e2ed
来源:简书

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值