RESTful架构总结

RESTful架构

1:什么是互联网软件

在传统开发中,软件开发主要是单片机开发,而网络开发主要是系统之间的通信,软件开发和网络开发之间交集较少,但是互联网的兴起,使的软件开发和网络开发开始开始融合,因此,网站的开发也可以采用软件开发的模式,即“互联网软件”,采用客户端/服务端的模式,建立在分布式系统上,通过互联网通信,具有高并发,高延时的特征。

RESTful就是一种互联网软件架构。

2:什么是REST?

REST是表述性状态传递

英文名:Representational State Tansfer

是Roy Fielding博士在他的2000年的博士论文中提出来的

注:Roy Fielding是HTTP规范的主要编写者之一,Apache服务软件的作者之一,Apache基金会的第一任主席,在他的论文中写到:“我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。REST指的是一组架构约束条件和原则。”

RESTful本身并没有提供新的技术和服务,它是基于HTTP、URI等web技术的标准和约束,原则上REST并不是HTTP唯一的,只是目前只有http实现了REST。REST是一种设计风格,不是规则。

表述性状态转移是一种架构约束条件和原则,主要是满足约束条件的的应用程序就是RESTful

3:HTTP方法

REST基本架构的四个方法

  • GET:用于获取数据
  • PUT:用于添加数据
  • DELETE:用于删除数据
  • POST:用于添加和更新数据
  • HEAD:获取资源的元数据。
  • OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。

4:Web Services

Web Services 是一个平台独立的,低耦合,自包含的,基于可编程的web应用程序,可使用xml标准来描述,发布,发现,协调和配置这些应用程序,用于开发分布式的互操作的应用程序

由于http直接传输数据,RESTful Web Services成为替代方法

5:RESTful基本概念

网站的访问就是你客户端和服务端的一种交互,在这种交互中,涉及到数据和转态的变化。互联网http协议是一种无状态协议,
所有状态都是保存在服务器上如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

  • 每一个URI代表一种资源;
  • 客户端和服务器之间,传递这种资源的某种表现层;
  • 客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。
  • 因为"资源"表示一种实体,所以应该是名词,URI不应该有动词,动词应该放在HTTP协议中。

1):资源和URI

REST说的是表述性转态转移,指的是资源的表述,在网路中,任何被引用的对象都是一个资源,既可以是具体的实体(手机号),也可以是抽象对象(关系,价值等)。

资源是可以被唯一标识的,URI(Uniform Resource Identify),统一资源定位符

URI设计的技巧:

2):统一资源接口

RESTful使用统一的接口,接口使用标准的http四大方法,并准守这些方法的语义,

  • GET:
    • 安全且幂等
    • 获取表示
    • 变更时获取表示(缓存)
    • 200(OK) - 表示已在响应中发出
    • 204(无内容) - 资源有空表示
    • 301(Moved Permanently) - 资源的URI已被更新
    • 303(See Other) - 其他(如,负载均衡)
    • 304(not modified)- 资源未更改(缓存)
    • 400 (bad request)- 指代坏请求(如,参数错误)
    • 404 (not found)- 资源不存在
    • 406 (not acceptable)- 服务端不支持所需表示
    • 500 (internal server error)- 通用错误响应
    • 503 (Service Unavailable)- 服务端当前无法处理请求
  • post
    • 不安全且不幂等
    • 使用服务端管理的(自动产生)的实例号创建资源
    • 创建子资源
    • 部分更新资源
    • 如果没有被修改,则不过更新资源(乐观锁)
    • 200(OK)- 如果现有资源已被更改
    • 201(created)- 如果新资源被创建
    • 202(accepted)- 已接受处理请求但尚未完成(异步处理)
    • 301(Moved Permanently)- 资源的URI被更新
    • 303(See Other)- 其他(如,负载均衡)
    • 400(bad request)- 指代坏请求
    • 404 (not found)- 资源不存在
    • 406 (not acceptable)- 服务端不支持所需表示
    • 409 (conflict)- 通用冲突
    • 412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突)
    • 415 (unsupported media type)- 接受到的表示不受支持
    • 500 (internal server error)- 通用错误响应
    • 503 (Service Unavailable)- 服务当前无法处理请求
  • PUT
    • 不安全但幂等
    • 用客户端管理的实例号创建一个资源
    • 通过替换的方式更新资源
    • 200 (OK)- 如果已存在资源被更改
    • 201 (created)- 如果新资源被创建
    • 301(Moved Permanently)- 资源的URI已更改
    • 303 (See Other)- 其他(如,负载均衡)
    • 400 (bad request)- 指代坏请求
    • 404 (not found)- 资源不存在
    • 406 (not acceptable)- 服务端不支持所需表示
    • 409 (conflict)- 通用冲突
    • 412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突)
    • 415 (unsupported media type)- 接受到的表示不受支持
    • 500 (internal server error)- 通用错误响应
    • 503 (Service Unavailable)- 服务当前无法处理请求
  • DELETE
    • 不安全但幂等
    • 删除资源
    • 200 (OK)- 资源已被删除
    • 301 (Moved Permanently)- 资源的URI已更改
    • 303 (See Other)- 其他,如负载均衡
    • 400 (bad request)- 指代坏请求
    • 404 (not found)- 资源不存在
    • 409 (conflict)- 通用冲突
    • 500 (internal server error)- 通用错误响应
    • 503 (Service Unavailable)- 服务端当前无法处理请求
  • POST和PUT在创建资源的区别在于,所创建的资源的名称(URI)是否由客户端决定。
  • 一些比较古老的基于浏览器的客户端,只能支持GET和POST两种方法。rails框架就支持通过隐藏参数_method=DELETE来传递真实的请求方法。Backbone这样的客户端MVC框架则允许传递_method传输和设置X-HTTP-Method-Override头来规避这个问题。
  • 统一接口并不阻止你扩展方法,只要方法对资源的操作有着具体的、可识别的语义即可,并能够保持整个接口的统一性。像WebDAV就对HTTP方法进行了扩展,增加了LOCK、UPLOCK等方法。而github的API则支持使用PATCH方法来进行issue的更新,像PATCH这种不是HTTP标准方法的,服务端需要考虑客户端是否能够支持的问题。
  • 统一资源接口要求使用标准的HTTP方法对资源进行操作,所以URI只应该来表示资源的名称,而不应该包括资源的操作。
  • 禁止缓存机制。 最简单的做法就是在你的HTTP响应里增加这样一个报头: Cache-control: no-cache。 但是,同时你也对失去了高效的缓存与再验证的支持(使用Etag等机制)。对于客户端来说,在为一个REST式服务实现程序客户端时,也应该充分利用现有的缓存机制,以免每次都重新获取表示。

3):资源的表述

客户端获取的只是资源的表述而已。 资源在外界的具体呈现,可以有多种表述(或成为表现、表示)形式,在客户端和服务端之间传送的也是资源的表述,而不是资源本身。 例如文本资源可以采用html、xml、json等格式,图片可以使用PNG或JPG展现出来。

客户端可以通过Accept头请求一种特定格式的表述,服务端则通过Content-Type告诉客户端资源的表述形式。

Content-type:application/json;charset=utf-8

Content-type:application/xml;charset=utf-8

Content-type:application/plain;charset=utf-8

Content-type:application/html;charset=utf-8

在URI里边带上版本号

使用URI后缀来区分表述格式

像rails框架,就支持使用/users.xml或/users.json来区分不同的格式。 这样的方式对于客户端来说,无疑是更为直观,但混淆了资源的名称和资源的表述形式。

如何处理不支持的表述格式

当服务器不支持所请求的表述格式,那么应该怎么办?若服务器不支持,它应该返回一个HTTP 406响应,表示拒绝处理该请求。

4):资源的链接

REST不仅仅是CURD的Web数据库架构,而且利用了超媒体的概念,把一个个把资源链接起来.

5):状态的转移

状态应该区分应用状态和资源状态,客户端负责维护应用状态,而服务端维护资源状态。

客户端与服务端的交互必须是无状态的,并在每一次请求中包含处理该请求所需的一切信息。

服务端不需要在请求间保留应用状态,只有在接受到实际请求的时候,服务端才会关注应用状态。

这种无状态通信原则,使得服务端和中介能够理解独立的请求和响应。

在多次请求中,同一客户端也不再需要依赖于同一服务器,方便实现高可扩展和高可用性的服务端。

浏览器随各次请求发出去的Cookie是被用于构建会话状态的。
当然,如果Cookie保存的是一些服务器不依赖于会话状态即可验证的信息(比如认证令牌),这样的Cookie也是符合REST原则的。

"会话"状态不是作为资源状态保存在服务端的,而是被客户端作为应用状态进行跟踪的。客户端应用状态在服务端提供的超媒体的指引下发生变迁。服务端通过超媒体告诉客户端当前状态有哪些后续状态可以进入。

API的设计

1:协议

API与用户的通信协议,总是使用HTTPs协议。

2:域名

应该尽量将API部署在专用域名之下。

https://api.example.com

如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。

https://example.org/api/

3:版本(Version)

应该将API的版本号放入URL。

https://api.example.com/v1/

将版本号放在HTTP头信息中,

4:路径

表示API的具体网址。

https://api.example.com/v1/a
https://api.example.com/v1/b
https://api.example.com/v1/c

参考资料

《RESTful架构详解》

《理解RESTful架构--阮一峰》

《RESTful设计指南API--阮一峰》

posted on 2016-04-28 19:10  借个火点烟  阅读(348)  评论(0编辑  收藏  举报