菜鸟笔记
提升您的技术认知

restfull 接口规范理解-ag真人游戏

restfull接口规范理解

restfull = representational state transfer 即表现层状态转移 加 ful (即形容词后缀) 则表示是形容词性的

而要理解restful架构,最好的方法就是去理解representational state transfer这个词组,直译过来就是「表现层状态转化」,其实它省略了主语。「表现层」其实指的是「资源」的「表现层」,所以通俗来讲就是:资源在网络中以某种表现形式进行状态转移。分解开来:

  • resource:资源,即数据。比如usenames/users/friends/menu/order等;
  • representational:某种表现形式,比如用json,xml,jpeg等;
  • state transfer:状态变化。通过http动词实现。

然后再来理解一个具体的restful架构——面向资源的架构(resource-oriented architecture,roa):

  • 资源是由uri来指定。所谓「上网」,就是与互联网上一系列的「资源」互动,调用它的uri。
  • 对资源的操作包括获取、创建、修改和删除资源,这些操作正好对应http协议提供的
  • get(获取网络中某个地址的资源),
    • post(创建资源也叫更新资源),
    • put(更新资源),
    • patch(更新网络资源),
    • delete(删除网络资源)
    • 最常见的就是get和post请求
    • 通过操作资源的表现形式来操作资源。具体表现形式,应该在http请求的头信息中用accept和content-type字段指定。
  • 资源的表现形式则是xml或者html,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。

应用于web服务,符合rest设计风格的web api称为restful api。它从以下三个方面资源进行定义:

  • 直观简短的资源地址:uri,比如:http://example.com/resources/;每一个uri代表一种资源;
  • 传输的资源:web服务接受与返回的互联网媒体类型,比如:json,xml,yaml等。
  • 对资源的操作:web服务在该资源上所支持的一系列请求方法(比如:post,get,put或delete)。

http请求方法在restful api中的典型应用:

资源 get put post delete
一组资源的uri,比如http://example.com/resources/ 列出uri,以及该资源组中每个资源的详细信息(后者可选)。 使用给定的一组资源替换当前整组资源。 在本组资源中创建/追加一个新的资源。该操作往往返回新资源的url。 删除整组资源。
单个资源的uri,比如http://example.com/resources/142 获取指定的资源的详细信息,格式可以自选一个合适的网络媒体类型(比如:xml、json等) 替换/创建指定的资源。并将其追加到相应的资源组中。 把指定的资源当做一个资源组,并在其下创建/追加一个新的元素,使其隶属于当前资源。 删除指定的元素。

rest的误解

现在看来,rest在2000年那个时代,确实是超前于时代的。web开发者社区对于http的设计意图存在着大量的误解,由此导致了对于http的大量低效率的误用。这个情况持续一直到2005年web 2.0的崛起。那个时候,dcom、ejb、soap/wsdl这些do风格的架构由于难以满足互联网环境对分布式应用架构设计的约束,与web自身的架构风格rest相冲突,很难融入到web之中。所谓的「web services」,其实除了将http作为底层的传输协议外,跟(互联网环境中的)真正的web没有什么关系。

而随着ruby on rails这个著名的web开发框架开始大力支持rest开发之后,一线的web开发者才真正接触到了rest。然而rails所支持的rest开发将对资源的操作局限于crud(创建、获取、修改、删除)的语义(即,将对资源的crud操作映射到 get/post/put/delete四个http方法),这其实是收窄了rest的适用范围。其他编程语言的web开发框架(例如java语言的 struts、spring mvc等等)也紧接着模仿了rails的方式开始支持rest开发,然而这更加导致了一线的web开发者误以为:rest开发就是 通过get/post/put/delete四个http方法对资源执行crud操作。甚至还有很多仅仅使用了http,而没有使用soap的web服 务api,都自称是rest风格(restful)的api。

对于什么才是真正的rest风格的误解是如此之多,而将rest作为一个便于营销的 buzzword的挂羊头卖狗肉者也是如此之多,以至于rest的创造者fielding终于忍无可忍了。2008年10月fielding写了一篇博 客,做出了一个非常明确的断言:rest apis must be hypertext-driven!(rest api必须是超文本驱动的!)超文本驱动这个理念变成了一个缩写词hateoas,这个缩写词来自于当初fielding博士论文中的一句话: hypermedia as the engine of application state(将超媒体作为应用状态的引擎)。其实超文本驱动(hypertext driven)的理念才是rest架构风格最核心的理念,也是rest风格的架构达到松耦合目标的根本原因。

rest设计进阶

当谈及rest成熟度时,一些人常常会引用richardson所提出来的rest成熟度模型(maturity model),并视之为正确的度量方法。

1.在架构中引入资源(resource)的概念。

大多数ws-*服务和pox都只是使用一个uri作为一个服务端口,也只使用一个http方法传输数据。这种做法相当于把http这个应用层协议降级为传输层协议用,《rest实战》也一再强调http是一种应用协议而不是传输协议。再好一点就是使用多个uri,然而不同的uri只是作为不同的调用入口,与此同时只使用同一个http方法传输数据。最常见的错误就是在uri中包含动词,比如uri http://example.com/getorder?orderid=1234,其实「资源」表示一种实体,所以应该是名词,动词应该放在http协议中。而与此同时uri也有可能破坏http get的安全性和幕等性,比如某个客户端在http://example.com/updateorder?id=1234&coffee=latte上执行get(而不是post),就能创建一笔新的咖啡订单(一个资源),按理来说get请求不能改变服务的任何状态。

2.每一个uri代表一种资源,支持http动词(即get,post,put,delete)。

此时使用多个uri的话,需要让不同的uri代表不同的资源(注意多个uri可能指向同一个resource,而一个uri不能指向不同resource。),同时使用多个http方法操作这些资源,例如使用post/get/put/delet分别进行crud操作。这时候http头和有效载荷都包含业务逻辑,例如http方法对应crud操作,http状态码对应操作结果的状态。我们现在看到的大多数所谓restful api做到的也就是这个级别。《rest实战》的译者也谈到:悟性差的人,理解到crud式web服务就满足了。而悟性好的人,可以彻底理解超文本驱动,甚至是与rest关系密切的语义网,最终达到 rest开发的最高境界。

网站地图