Rest Notes-将REST应用于HTTP

摘要: 超文本移交协议(HTTP)在Web架构中既作为在Web组件之间通信的主要的应用级协议,也作为特别为移交资源的表述而设计的唯一的协议(现在并不是唯一,还有COAP协议)。

正文:

将REST应用于HTTP

超文本移交协议(HTTP)在Web架构中既作为在Web组件之间通信的主要的应用级协议,也作为特别为移交资源的表述而设计的唯一的协议(现在并不是唯一,还有COAP协议)。

REST用来识别早期HTTP协议中的问题,并指定了一个可以和HTTP1.0互操作的协议子集,然后分析HTTP1.1的扩展提议,并最终诞生了HTTP1.1

可扩展性

REST的主要目标之一是在一个已部署的架构中支持逐渐的和片段的修改

  • 协议版本控制

    通过主版本和次版本号来区分(1.0 1.1 2.0),其版本信息代表的是消息发送者对协议的支持能力

  • 可扩展的协议元素

    通过将解析和转发HTTP消息的规则与新的HTTP协议元素的相关语义分离开,解决了中间组件更新部署问题

    扩大了响应码区间,100-599

  • 升级

    HTTP1.1新增了Upgrade头,用来再通信双方进行协商协议版本

自描述的信息

REST要求组件之间消息是自描述的,以便支持中间组件对于交互的处理。然而早期HTTP协议的一些方面并不是自描述的(请求中缺乏主机标识、无法根据语法来区分消息控制数据和表述元数据等)

  • Host(主机)

    早期的HTTP请求中不会携带host头部信息,这导致了无法区分我访问的到底是服务器上的哪个站点

    例如我们使用Github pages搭建静态博客时候,都将域名解析到Github的某个IP(192.30.252.154),大家通过不同域名访问的却是不同页面。这个就是通过不同的Host来区分的

  • 分层编码

    HTTP为了描述表述的元数据,继承了多用途互联网邮件扩展(MIME)的语法,MIME没有定义分层的媒体类型

  • 语义独立性

    如上面可扩展的协议元素所述,HTTP消息的解析与其语义是相分离的

  • 传输独立性

    早期的HTTP协议包括大多数的HTTP/1.0的实现,使用底层的传输协议来表示响应消息的结束。服务器通过关闭TCP连接来表明响应消息的结束,但不幸的是则会导致:客户端没有办法区分一个完成的响应和因为某种故障异常而断开的响应。为了解决这个问题在HTTP/1.0中重新定义了Content-Length头信息字段,以表示消息体的字节长度,并且在HTTP/1.1中引入了“chunked”(分块)这个移交编码

    chunked编码允许表述在其生成阶段的开始时尺寸是未知的,通过一系列分块来描述它的界限,每个分块的尺寸可在被发送之前单独设置

  • 尺寸限制

    对于应用层协议的灵活性而言,常见的障碍是在协议的参数上过度指定尺寸限制的倾向

    在HTTP协议中并没有限制URI的长度、头信息字段的长度、表述的长度、任何由一列条目组成的字段值的长度

  • 缓存控制

    REST努力在高效率的、低效率的行为和其所期待的语义透明的缓存行为之间取得平衡,因此它允许由应用确定缓存需求,而不是将该需求硬编码在协议本身之中,这对于HTTP协议来说是至关重要的

    HTTP/1.1通过添加Cache-Control、Age、Etag、Vary几个头信息字段来达到这个目标

性能

  • 持久连接

    早期的HTTP协议每个连接只能发送单个请求/响应,尽管实现起来简单,但是它对于底层TCP传输机制的使用非常低效。原因在于每次交互都要付出重新建立连接的开销

    对于HTTP/1.0,通过使用在Connection头信息字段中的“keep-alive”指令来达到这个目标,但是如果转发给不理解该指令的中间组件会造成连接关闭,HTTP1.1最终把默认的持久连接作为了默认的选项,如果要关闭连接,则需要发送close的指令

  • 直写式缓存

    HTTP协议不支持回写式缓存,HTTP缓存不能假设通过它写入的消息与来自相同资源的后续请求可能获取的内容是相同的,因此它不能缓存一个PUT请求的消息体,并且将其内容重用于稍后的GET请求的响应

    缺乏回写式缓存并不会对性能产生严重影响

    这里的PUT请求是写入动作,幂等的,相当于对资源赋值操作

REST在HTTP中的不匹配

在HTTP协议中存在一些架构不匹配,一些是由于标准过程之外部署的第三方扩展所导致的,其他的则是由于与已部署的HTTP/1.0组件保持兼容的必要性所导致的

  • 区分非权威的响应

    没有一致的机制来区分一个响应是来自于源服务器还是中间的某一个组件(走的缓存没有走来源服务器),虽然HTTP1.1中定义了Warning消息头,但是在实践中并未广泛使用。

  • Cookie

    Cookie是不透明的数据,来源服务器通过将它包括在一个Set-Cookie响应头信息字段中,将它设置给一个用户代理,用户代理在所有将来的请求中包括这个相同的Cookie,直到被替换或者过期

    Cookie违反了REST,因为它们允许数据在没有充分表明其语义的情况下对其进行传递,这会成为一个安全和隐私方面的关注点(结合使用Cookie和Referer头信息字段,有可能当用户多个站点浏览时对其进行跟踪)

  • 响应与请求相匹配

    当需要描述哪一个响应属于哪一个请求的时候,HTTP消息并不是自描述的

    早期的HTTP协议并没有考虑到需要将响应与相关的请求绑定在一起的消息控制数据,因此请求的顺序决定了响应的顺序,这意味着HTTP依赖于传输层的连接来确定这一匹配