09.RESTful服务
周志明架构课-架构师视角
09.RESTful服务:从面向过程编程到面向资源编程
行文思路:
- RESTful与RPC不是同一类型的东西
- RESTful该怎么理解
- RESTful有什么特征
- 有什么优势
另一种主流的远程服务访问风格:RESTful服务
RESTful与RPC区别的本质
其实两者另不是同一类型的东西,充其量只能算是有一些相似。在应用中会有一些重合的地方,两者差异的核心是抽象的目标不一样,也就是面向资源与面向过程的编程思想的区别。
RESTful并不是一种远程调用协议。说到协议啊,一般是都有一定规范性和强制性的。但RESTful却什么都没有,所以只能说RESTful只是一种风格。而这种风格一般还挺难达到的
在使用范围上RPC和RESTful是两种主流的远程调用方式,在使用上确实有重合。
RESTful讨论的是架构风格与网络的软件架构设计,RPC只是一种远程服务调用的方式。这逼格明显不一样好不啦。
对于RESTful的理解
Representational State Transfer ,表征状态转移。
ps:哇塞,太抽象了。什么表征,什么的状态,从哪转移到哪儿。这算是什么狗屁定义呀
等会再来管个定义吧。先来看看几个概念
- 资源,什么是资源?我理解的经常在网上看到的一些信息呀,内容呀,都可以称为资源。如果你喜欢用浏览器看小说的话,就可以把显示小说内容看作是一个资源。
- 表征,哪什么表征就是什么呢?显示小说的网页就是一种表征形式啦。所谓的表征就是一种资源的表现形式而矣
- 状态,什么的状态?在特定语境下产生的上下文信息就是状态,比如你在读小说的时候一章读完了,点下一章的按钮。但服务器那知道你现在读的是哪一章呀,所以现在读的这一章就可以称为是一个状态
- 转移,了解了上面的资源、表征、状态的例子,那转移就好理解了,由服务端通过某种方式,把这一章转变成下一章,这就是表征状态转移了。
这几个概念还是挺好理解的,别放松,接着再来三个概念
- 统一接口, URI的含义是统一资源标识符,是一个名词,如何让他表示出动词的含义呢?其实这些HTTP协议都给提供好了一套标准的接口,你肯定很熟悉:GET\POST\HEAD\PUT\DELETE\TRACE\OPTIONS,也就是说通过HTTP协议定义好的这些动作就可以让服务器乖乖的听话了,要什么给什么
- 超文本驱动,这个有点意思,我们都是通过浏览器来操作从而向服务端发送请求的,但是作为通用客户端的浏览器,它是不用管这些的,只是给我们提供一个地址栏而矣,那在打开一个网页之后,其它所有在网页的操作,都是由网页本身来控制的。那网页有什么链接,有什么按钮,也都是它自己说了算。而这些也都是属于超文本的内容,在这里我们都需要有这样一个思路的细化,不能觉得浏览器是万能的,它也只是一个通用的工具,做好自己通用的事儿就行了。
- 自描述,由于表征是多种多样的,要想让浏览器(客户端)了解服务器到底响应了点啥内容,这还得在响应的信息里标识出来。我们常见的Content-Type,就是干这事儿的。
RESTful风格的特征
服务端与客户端分离
这一个特征可以参考,前后端分离架构来理解
无状态
REST不希望服务端维护状态,每次请求包含必要的上下文信息,会话由客户端保存,服务端根据客户状传递的状态信息进行处理,并驱动整个应用状态变迁
可缓存
由于无状态,所以每次请求都得带上大量的冗余信息,为了解决这个问题,提出的这么一个特征,也是一个用于提升响应性能的手段
分层系统
客户端一般不需要知道是否直接连接到了最终的服务器,或者是连接到路径上的中间服务器
统一接口
REST希望开发者可以面向资源来编程,希望软件系统的设计重点放在对抽象系统该有哪些资源上,而不是哪些行为上。一般来说面向资源的抽象程度通常比较高。
ps:我觉得这块一可以结合,软件的复杂度,以及领域驱动设计来理解。这样大家就不再纠结为什么抽象资源比面向过程更有优势这一点了。架构设计的本质,是降低软件复杂度再来的影响,那咋降低呢?把变化控制来一个小的范围内,这是一个思路。
那怎么才能在架构设计中合理恰当地利用统一接口呢?RESTful的提出者,Fielding 给出了三个建议
- 第一,系统要能做到每次请求中都包含资源的 ID,所有操作均通过资源 ID 来进行;
- 第二,每个资源都应该是自描述的消息;
- 第三,通过超文本来驱动应用状态的转移。
按需编码
任何按照客户端(如浏览器)的请求,将可执行的软件程序从服务器发送到客户端的技术
面向资源设计有什么好处呢?
- 降低服务接口的学习成本
- 资源天然具有集合与层次结构:以方法为中心抽象的接口,由于方法是动词,逻辑上决定了每个接口都是互相独立的;但以资源为中心抽象的接口,由于资源是名词,天然就可以产生集合与层次结构。
- REST绑定于HTTP协议