RESTful服务至上实践

正文主要读者

看了一样响老师写的小说《人于民歌里》。

引言

细细读下来,文笔流畅,语言生动,幽默。心理描写,细致入微,景物描写,如临。

REST是什么

小说写了我之年轻故事。我同狼子的友谊,晴枫之间的情爱。

  统一接口

小说从狼子负责风花雪月,我背负伤悲感秋开始,进入自家的常青初中阶段:灿烂的骄阳龙。我和狼子好之跟同性恋似的。文中初中的自身,羞涩,学习好。而且爱上了面貌秀丽,性格乖巧的陆晴枫。我背后的暗恋其。心中的其:衣着白色的长裙,清逸如风。晴枫学习吧坏好,她的名直在自家后面。当时底自家,一直发错觉:以后自己的结婚证书上,我的名会无会见紧挨着陆晴枫呢?文笔幽默,读来吃丁发笑。

    因资源

步入高中,进入人生之雨季。我痴迷上勾画小说,学业一塌糊涂。高中在烦闷又闷,我直接活在协调的社会风气里,窥探着外面的世界。狼子,晴枫他们的复,成了自身灰暗生活里之想望和惊喜,虽然我跟晴枫的信无关风月。但那些信,却成为了一束光,照耀着我昏暗的活着。

    经过特色来操作资源

高中的我,伤感迷茫,既欲爱的良人明白自己的旨意,又会看穿自己之弄虚作假。我竟然多潮幻想和晴枫结婚。她是那美,那么清逸。

    从今描述的消息

内,我跟狼子之间以爱情观生分歧,闹了同涂鸦别扭。在自眼里,狼子就是一个浪子,对感情无负,不忠诚。最后,我知,云玲是他的最好易,其他都是拿就。

    超媒体即采用状态引擎(HATEOAS)

高中的结尾阶段,鼓起勇气,把六年之幻想付诸笔尖,写进信里。没悟出,却迎来了晴枫的对。那是自年轻最喜悦的时段。但那昙花一现的爱情维持了没抢,我倒反复复的分分合合不过大凡心灵之畏首畏尾,不自信。好像总有一个响声以说:那还要休是爱。

  无状态

当自己又瞅晴枫,她都没那清逸如风的感觉了,而是同样栽日暮苍山底惆怅。文中我十分后悔,我怀念挽回,但终归起响声告诉我:放了晴枫。心底的畏首畏尾,担心那不是情,担心吃莫了它们想如果的爱情。也许,晴风要之非常简单,只要同自家当一块就是是美满的。

  可缓存

常青时不了解爱,读懂时曾失去,天各一正。

  C-S架构

后来的自己,进入单恋。大学毕业后,感情事业都非沿。我同狼子联系越来越少,在爱情观上无一致,我猛然发现,爱情远了,友情吗一点一点地多去。

  支行系统

常青,是何其亮丽的词。青春里发生快,有不明;有诗意有感伤;有暗恋有甜。那些平常的生活因为咱们的儿女情长多了诗意,多了糊涂的美。

  按需编码(可选)

各国一样截青春还来少数只主旋律:友情,爱情。友情弥足珍贵,爱情刻骨铭心。因为那儿的我们惟有,羞涩,带在阳光的气息,带在淡淡的发愁。把最实际的自展现在对方前。没有矫揉造作,没有敌意。不禁想起辛弃疾的同等首词:

REST快速提示

豆蔻年华不识愁滋味,爱上重叠楼。爱上层楼,为赋予新词强说愁。

  下HTTP动词表示有含义

今天识尽愁滋味,欲说还休。欲说还休,却道天凉好个秋。

  成立的资源名

文中的各级一样轴插图都特别得意。意境悠远,浮想联翩。好像自己所涉之年青,那些只友谊,那些美好的当儿,一点点地发在前面。我仿佛又当青春里走了扳平被,看到了过去的自己。

  XML和JSON

喜求点原著人数当风里

  始建适当粒度的资源

  设想连通性

定义

  幂等性

  安全

HTTP动词

  GET

  PUT

  POST

  PUT和POST的创建于

  DELETE

资源命名

  资源URI示例

  资源命名的反例

  复数

回表征

  资源通过链接的可发现性(HATEOAS续)

    最好小化链接推荐

    链接格式

  卷入响应

  处理跨域问题

    支持CORS

    支持JSONP

询问,过滤和分页

  结果限制

    据此范围标记进行限定

    于是字符串查询参数进行限

    因范围之应

  分页

  结果的过滤与排序

    过滤

    排序

劳版本管理

  通过情节商支持版本管理

  当没有点名版本时,返回什么版本?

  请不支持之本子

  哎呀时候理应创建一个新本子?

    破坏性的改

    非破坏性的改

  版本控制应在什么级别出现?

  以Content-Location来增长响应

  带有Content-Type的链接

  检索有支持之版

    自当而且支持小只本子?

    弃用

    自家哪些告客户端给弃用的资源?

日期/时间处理

  Body内容被的日期/时间序列化

  HTTP
Headers中之日子/时间序列化

保障服务的安

  身份验证

  传输安全

  授权

  应用程序安全

缓存和可伸缩性

  ETag Header

HTTP状态码(前10)

外加资源

  书籍

  网站

 

本文主要读者

  该最佳实践文档适用于对RESTful
Web服务感兴趣之开发人员,该服务吗超越多个劳务之零部件提供了比高的可靠性以及一致性。按照本文的指导,可高效、广泛、公开地为内外部客户采用。

  本文中之指导原则一致适用于工程师等,他们希望使这些根据最佳实践标准开发的服务。虽然她们进一步体贴缓存、代理规则、监听和安全等连锁方,但是该文档能作为一如既往份包含所有品种服务的总指南。

  另外,通过由这些点原则,管理人员了解及创造公共的、提供高稳定的劳动所要花的极力,他们吧不过从中受益。

 

引言

  现今曾发恢宏有关RESTful
Web服务至上实践的有关资料(详见本文最后之连带文献有)。由于撰文的辰不一,许多材料中之始末是矛盾的。此外,想如果通过查阅文献来打探这种服务之提高是无太长的。为了打探RESTful这等同概念,至少用查阅三顶五论有关文献,而本文将会帮您加快这同经过——摒弃多余的讨论,最大化地提炼出REST的特等实践和规范。

  与其说REST是千篇一律效仿标准,REST更如是如出一辙种植规格的会师。除了六只重大的法外虽无其余的标准了。实际上,虽然有所谓的“最佳实践”和专业,但这些东西都同教斗争一样,在持续地演变。

  本文围绕REST的广问题提出了意见跟仿食谱式的座谈,并透过介绍一些简单的背景知识对创建真实地下的事先生产环境被千篇一律的REST服务提供文化。本文收集了自其它渠道的音,经历了一次次底破产后不断改进。

  但对REST模式是否肯定比SOAP好用本时有发生于生争(反之亦然),也许在少数情况下遵循需创造SOAP服务。本文在提及SOAP时并未花较充分篇幅来谈谈其的对立优点。相反由于技术和行业在不断进步,我们用连续坚持不懈我们的比方–REST是这筹web服务的特等方式。

  第一有的概述REST的含义、设计则及它们的特种的处。第二局部罗列了部分略带贴士来记忆REST的劳务意见。之后的一部分则会重复尖锐地也web服务创建人员提供有细节的支撑与座谈,来落实一个能够公开展示在生育条件受到之赛质量REST服务。

 

REST是什么?

  REST架构方式讲述了六种设计则。这些用于架构的统筹则,最早是出于Roy
Fielding在他的博士论文中提出并定义了RESTful风格。(详见http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm)

  六独统筹则分别是:

  • 联合接口
  • 无状态
  • 可缓冲
  • C-S架构
  • 分段系统
  • 按需编码

  以下是这些规划则的详实讨论:

合并接口

  统一接口准则定义了客户端和服务端之间的接口,简化和分手了框架结构,这样一来每个片都只是独自演化。以下是接口统一之季只尺码:

  基于资源

  不同资源需要因此URI来唯一标识。返回给客户端的特性和资源本身在概念上有所不同,例如服务端不会见直接传送一个数据库资源,然而,一些HTML、XML或JSON数据可知亮部分数据库记录,如用芬兰语来表达要用UTF-8编码则使依据请求和服务器实现的细节来支配。

  通过特征来操作资源

  当客户端收到包含元数据的资源的特征时,在发出权力的气象下,客户端都掌握的够的信,可以对服务端的资源拓展删改。

  自描述的音信

  每条信息都富含足够的数量用于确认消息该怎么处理。例如要出于网络媒体类型(已解的比方MIME类型)来认可要调用哪个解析器。响应同样为标志了它的缓存能力。

  超媒体即祭状态引擎(HATEOAS)

  客户端通过body内容、查询串参数、请求头和URI(资源名称)来传送状态。服务端通过body内容,响应码和响应头传送状态让客户端。这项技能为称超媒体(或超文本链接)。

  除了上述内容他,HATEOS也象征,必要之上链接也可是给含有在回的body(或头部)中,以供URI来寻觅对象自我或涉及对象。下文将对准这开展更详实的阐释。

  统一接口是每个REST服务规划时的必备准则。

无状态

  正如REST是REpresentational State
Transfer的缩写,无状态异常重要。本质上,这表明了处理要所需要的状态已经包含在求我里,也发出或是URI的同等有的、查询串参数、body或头部。URI能够唯一标识每个资源,body中吗富含了资源的转态(或转态变更情况)。之后,服务器将展开拍卖,将相关的状态或资源通过头部、状态及响应body传递让客户端。

  从事我们顿时同一业的大部分人犹习惯使用容器来编程,容器中产生一个“会话”的定义,用于在差不多只HTTP请求下维持状态。在REST中,如果假定以差不多个请求下维持用户状态,客户端必须概括客户端的兼具信息来好请求,必要常常再次发送请求。自从服务端不待保障、更新或传递会话状态后,无状态性得到了还充分之延展。此外,负载均衡器无需担心和无状态系统里头的对话。

  所以状态及资源中有啊区别?服务器对状态,或者说是应用状态,所关切之触发是以此时此刻对话或请求被要完成请求所要的多少。而资源,或者说是资源状态,则是概念了资源特色的数据,例如存储在数据库被的数量。由此可见,应用状态是是乘客户端和请求的更改如果改变之数码。相反,资源状态对于发出请求的客户端的话是无换的。

  于网络利用之某平等特定岗位上张一个返按钮,是坐它们要您能够按照自然的一一来操作也?其实是为其违反了无状态的规范。有众多请勿守无状态原则的案例,例如3-Legged
OAuth,API调用速度限制等。但要么如尽可能保证服务器遭受莫待以差不多个请求下保持利用状态。

可缓存

  在万维网上,客户端好缓存页面的响应内容。因此应都应隐式或显式的定义为而缓存的,若不足缓存则只要避免客户端在屡要后之所以旧数据还是污染数据来响应。管理得当的休养生息存会部分地或全地除了客户端和服务端之间的互,进一步改善性及延展性。

C-S架构

  统一接口使得客户端与服务端相互分开。关注分离意味什么?打个如,客户端不需仓储数据,数据都预留在服务端内部,这样让客户端代码的可移植性得到了晋级;而服务端不需要考虑用户接口及用户状态,这样一来服务端将越加简便易行容易拓展。只要接口不转移,服务端和客户端可独自地进行研发和替换。

分层系统

  客户端通常无法表明自己是直或者间接与端服务器进行连接。中介服务器可以经过启用负载均衡或供共享缓存来提升系统的延展性。分层时同要考虑安全策略。

按需编码(可选)

  服务端通过传输可实施逻辑给客户端,从而为其现拓展及定制功能。相关的事例有编译组件Java
applets和客户端脚本JavaScript。

  遵从上述标准,与REST架构风格保持一致,能被各种分布式超媒体系统具备梦想之自然属性,比如高性能,延展性,简洁,可变性,可视化,可移植性和可靠性。

  提示:REST架构中的宏图则遭到,只有按照需要编码为可卜项。如果有服务违反了其他随意一件则,严格意思上无克称之为RESTful风格。

 

REST快速提示

  (根据上面提到的六个规格)不管在技术上是不是RESTful的,这里发生部分近乎REST概念的提议。遵循它,可以实现更好、更管用之劳动:

运用HTTP动词表示有意思

  任何API的使用者能发送GET、POST、PUT和DELETE请求,它们非常怪程度显著了所吃要的目的。同时,GET请求不可知更改任何秘密的资源数量。测量和跟踪仍可能产生,但单纯见面更新数据而非见面更新由URI标识的资源数量。

合理的资源名

  合理之资源名称或路径(如/posts/23若无是/api?type=posts&id=23)可以再明确一个要的目的。使用URL查询串来过滤数据是深好之法门,但非应当用于固定资源名称。

  适当的资源名称也服务端请求提供上下文,增加服务端API的可理解性。通过URI名称分层地翻资源,可以吃使用者提供一个协调之、容易理解的资源层次,以当他们之应用程序上采取。资源名称应当是名词,避免吗动词。使用HTTP方法来指定要的动作有,能为工作越的一清二楚。

XML和JSON

  建议默认支持json,并且,除非花费很惊人,否则就是同时支持json和xml。在理想状态下,让使用者仅经过改扩展名.xml和.json来切换类型。此外,对于支持ajax风格的用户界面,一个叫包裹的应是殊有扶持的。提供一个为卷入的应,在默认的要发单独放展名的情下,例如:.wjson和.wxml,表明客户端请求一个给包裹的json或xml响应(请参见下的卷入响应)。

  “标准”中对json的求充分少。并且这些需要单是语法性质的,无关内容格式和布局。换句话说,REST服务端调用的json响应是说道的等同组成部分——在正规被并未相关描述。更多关于json数据格式可以于http://www.json.org/上找到。

  关于REST服务中xml的应用,xml的专业和约定除了使语法正确的标签及文本外没有其余的来意。特别地,命名空间不是为不应是叫下以REST服务端的前后文中。xml的归来重新仿佛于json——简单、容易看,没有模式以及命名空间的细节表现——仅仅是数码和链接。如果她比当下又复杂的话,参看本节的率先段落——使用xml的工本是危言耸听之。鉴于我们的经验,很少有人利用xml作为响应。在其给统统淘汰之前,这是最后一个可为肯定的地方。

开创适当粒度的资源

  同开始,系统遭到模拟底层应用程序域或数据库架构的API更易于被创造。最终,你晤面期待用这些劳务还做及手拉手——利用基本上起底层资源减少通信量。在开创独立的资源之后再行创更甚粒度的资源,比打再老的共集中创建于生粒度的资源越来越爱有。从部分微的善定义之资源开始,创建CRUD(增删查改)功能,可以要资源的始建变得重便于。随后,你可创建这些根据用例和减少通信量的资源。

考虑连通性

  REST的规律之一就是是连通性——通过超媒体链接实现。当以应中归链接时,api变的再度具备从描述性,而于并未它常服务端依然可用。至少,接口本身可以呢客户端提供什么样寻找数据的参阅。此外,在通过POST方法创建资源时,还好应用头位置包含一个链接。对于响应中支持分页的集合,”first”、
“last”、”next”、和”prev”链接至少是老实用之。

 

定义

幂等性

  不要打字面意思来解什么是幂等性,恰恰相反,这同某些功能紊乱的世界无关。下面是来维基百科的讲:

于微机对中,术语幂相当用于更健全地讲述一个操作,一赖还是数行该操作有的结果是如出一辙的。根据使用之上下文,这说不定有异的意义。例如,在法或者子例程调用具有副作用的景况下,意味着在率先调用之后被涂改的状态呢保持不更换。

  从REST服务端的角度来拘禁,由于操作(或服务端调用)是幂等的,客户端好用更的调用而来同样之结果——在编程语言中操作像是一个”setter”(设置)方法。换句话说,就是用多单相同的伸手与祭单个请求效果一样。注意,当幂等操作以服务器上生同样之结果(副作用),响应本身或是差的(例如当差不多只请求中,资源的状态恐怕会见转)。

  PUT和DELETE方法为定义为凡幂等的。查看http请求中delete动词的警示信息,可以参考下文的DELETE部分。GET、HEAD、OPTIO和TRACE方法从被定义也平安的办法后,也于定义也幂等的。参照下关于安全的截。

安全

  来自维基百科:

有的计(例如GET、HEAD、OPTIONS和TRACE)被定义为平安的计,这表示它们只是于用来信息寻找,而无能够改服务器的状态。换句话说,它们不见面有副作用,除了相对来说无害的影响要日志、缓存、横幅广告还是计数服务等。任意的GET请求,不考虑以状态的上下文,都吃看是高枕无忧之。

  总之,安全意味着调用的道不见面惹副作用。因此,客户端可数使用安全的恳求而无用担心对服务端产生其他副作用。这代表服务端必须遵从GET、HEAD、OPTIONS和TRACE操作的平安概念。否则,除了针对消费端产生模糊外,它还会见招致Web缓存,搜索引擎和另外活动代理的问题——这将于服务器上发生意想不到的产物。

  根据定义,安全操作是幂等的,因为它在服务器上起同样之结果。

  安全之道给实现吗单独读操作。然而,安全并无表示服务器必须每次都归相同的响应。

 

HTTP动词

  Http动词主要按“统一接口”规则,并提供被我们相应的冲名词的资源的动作。最紧要还是最好常用的http动词(或者叫做方法,这样叫可能更恰当些)有POST、GET、PUT和DELETE。这些分别指向应于创建、读取、更新与去(CRUD)操作。也发出成百上千任何的动词,但是利用效率比较小。在这些用比较少之艺术吃,OPTIONS和HEAD往往利用得重多。

GET

  HTTP的GET方法用于检索(或读取)资源的数据。在科学的请路径下,GET方法会返回一个xml或者json格式的数,以及一个200底HTTP响应代码(表示对返回结果)。在错情况下,它通常返回404(不存)或400(错误的求)。

  例如:

*  GET http://www.example.com/customers/12345*
  GET http://www.example.com/customers/12345/orders
  GET http://www.example.com/buckets/sample

  按照HTTP的设计规范,GET(以及附带的HEAD)请求单用于读取数据而不转多少。因此,这种应用办法吃看是平安之。也就是说,它们的调用没有多少修改或者染的风险——调用1浅以及调用10浅或没被调用的意义等同。此外,GET(以及HEAD)是幂等的,这象征使用多独一样之呼吁与运用单个的呼吁最终还拥有相同的结果。

  不要通过GET暴露不安全之操作——它应永远都不克改服务器上的任何资源。

PUT

  PUT通常为用来创新资源。通过PUT请求一个就知道的资源URI时,需要以求的body中含有对原资源的创新数据。

  不过,在资源ID是由于客服端而休服务端提供的图景下,PUT同样好让用来创造资源。换句话说,如果PUT请求的URI中带有的资源ID值在服务器上无存,则用来创造资源。同时请的body中须含有要创建的资源的数。有人以为就会时有发生歧义,所以只有真的用,使用这种措施来创造资源应该吃慎用。

  或者我们吧得以body中提供由客户端定义的资源ID然后使用POST来创造新的资源——假设请求的URI中未分包要创造的资源ID(参见下POST的一些)。

  例如:

*  PUT http://www.example.com/customers/12345*
  PUT http://www.example.com/customers/12345/orders/98765
  PUT http://www.example.com/buckets/secret\_stuff

  当使用PUT操作更新成功时,会回来200(或者返回204,表示回去的body中莫含有其他内容)。如果应用PUT请求创建资源,成功返回的HTTP状态码是201。响应的body是可选的——如果提供的口舌将见面耗费又多之拉动富。在创立资源时从没必要通过头部的职返回链接,因为客户端就设置了资源ID。请参见下的归值部分。

  PUT不是一个平安之操作,因为她会改(或创造)服务器上之状态,但它们是幂等的。换句话说,如果你利用PUT创建或者更新资源,然后还调用,资源还有而状态不会见发生变化。

  例如,如果在资源增量计数器中调用PUT,那么是调用方法就是不再是幂等的。这种情形有时候会发出,且可能得验证她是匪幂等性的。不过,建议维持PUT请求的幂等性。并强烈建议非幂等性的求使用POST。

POST

  POST请求时于用来创造新的资源,特别是为用来创造于属于资源。从属于资源就属于其他资源(如慈父资源)的资源。换句话说,当创建一个初资源时,POST请求发送给父资源,服务端负责将新资源与大资源进行关联,并分配一个ID(新资源的URI),等等。

  例如:

  POST http://www.example.com/customers
  POST http://www.example.com/customers/12345/orders

  当创建成功时,返回HTTP状态码201,并顺便一个职头信息,其中包含指向最先创建的资源的链接。

  POST请求既不是安全之又无是幂等的,因此其让定义为非幂等性资源要。使用简单个一律之POST请求很可能会见导致创建两只带有相同信息之资源。

PUT和POST的创始于

  总之,我们建议下POST来创造资源。当由客户端来控制新资源有何等URI(通过资源名称或者ID)时,使用PUT:即只要客户端知道URI(或资源ID)是什么,则针对该URI使用PUT请求。否则,当由服务器或劳务端来控制创办的资源的URI时虽然动用POST请求。换句话说,当客户端在开创之前未懂得(或无法知晓)结果的URI时,使用POST请求来创造新的资源。

DELETE

  DELETE很容易了解。它叫用来冲URI标识删除资源。

  例如:

  DELETE http://www.example.com/customers/12345
  DELETE http://www.example.com/customers/12345/orders
  DELETE http://www.example.com/buckets/sample

  当去成功时,返回HTTP状态码200(表示对),同时会顺便一个应体body,body中恐怕包含了删除项之数(这会占用部分大网带来富),或者封装的响应(参见下的返回值)。也得以回来HTTP状态码204(表示无论是内容)表示没有响应体。总之,可以回状态码204代表没有响应体,或者返回状态码200以附带JSON风格的响应体。

  根据HTTP规范,DELETE操作是幂等的。如果你针对一个资源拓展DELETE操作,资源就深受移除了。在资源上翻来覆去调用DELETE最终促成的结果还一致:即资源被移除了。但要用DELETE的操作用于计数器(资源中),则DETELE将不再是幂等的。如前方所陈述,只要数据没有吃更新,统计和测量的用法依然可于当是幂等的。建议非幂等性的资源要使用POST操作。

  然而,这里产生一个有关DELETE幂等性的警示。在一个资源达到第二不好调动用DELETE往往会回去404(未找到),因为该资源就给移除了,所以找不交了。这使得DELETE操作不再是幂等的。如果资源是打数据库中剔除而无是让略去地记为去,这种状态需要得体让步。

  下表总结出了最主要HTTP的章程及资源URI,以及推荐的返回值:

HTTP请求

/customers

/customers/{id}

GET

200(正确),用户列表。使用分页、排序和过滤大导航列表。

200(正确),查找单个用户。如果ID没有找到或ID无效则归404(未找到)。

PUT

404(未找到),除非你想以普集合中创新/替换每个资源。

200(正确)或204(无内容)。如果没找到ID或ID无效则回404(未找到)。

POST

201(创建),带有链接到/customers/{id}的职头信息,包含新的ID。

404(未找到)

DELETE

404(未找到),除非您想去所有集合——通常不给允许。

200(正确)。如果没有找到ID或ID无效则赶回404(未找到)。

 

资源命名

  除了当地使HTTP动词,在创造一个足掌握的、易于使的Web服务API时,资源命名可以说凡是最好具有争议与极要紧的定义。一个吓的资源命名,它所对应之API看起还直观并且爱使。相反,如果命名不好,同样的API会给人倍感格外笨而难以知晓以及运。当您用吗你的新API创建资源URL时,这里产生有小技巧值得借鉴。

  从实质上说话,一个RESTFul
API最终都足以让略去地作为是同样积URI的汇聚,HTTP调用这些URI以及有用JSON和(或)XML表示的资源,它们中起众多包含了互动关联的链接。RESTful的而寻址能力要靠URI。每个资源且发温馨的地方或URI——服务器会提供的各国一个可行的信还好作为资源来明。统一接口的准绳有地经URI和HTTP动词的结缘来化解,并符合利用标准和约定。

  在支配你系统受到使利用的资源时,使用名词来命名这些资源,而休是为此动词或动作来定名。换句话说,一个RESTful
URI应该干到一个切实可行的资源,而无是干到一个动作。另外,名词还装有局部动词没有底习性,这也是其他一个阳的要素。

  一些资源的例子:

  • 系的用户
  • 学员注册之课程
  • 一个用户帖子的岁月轴
  • 关怀其他用户的用户
  • 同等首关于骑马的稿子

  服务套件中之每个资源最少发生一个URI来标识。如果这个URI能表示必定之义并且能够充分描述她所表示的资源,那么它们便是一个太好的命名。URI应该有可预测性和分支结构,这将推进提高其的可理解性和可用性的:可预测指的是资源应该跟名称保持一致;而分指的是数据具有涉达成之构造。这并非REST规则或规范,但是它们加重了对API的概念。

  RESTful
API是供给消费端的。URI的名称和结构应该以她所抒发的义传达给消费者。通常我们那个为难掌握数码的鄂是什么,但是于您的数量上而当很有或夺尝试找到要返回给客户端的数码是啊。API是吗客户端而设计的,而无是啊汝的多少。

  假设我们现在如果讲述一个包括客户、订单,列表项,产品等力量的订单系统。考虑一下我们欠如何来叙述在斯服务着所涉及到的资源的URIs:

资源URI示例

  为了在系统受到插(创建)一个初的用户,我们得以:

  POST http://www.example.com/customers

 

  读取编号吧33245的用户信息:

  GET http://www.example.com/customers/33245

  使用PUT和DELETE来请求相同之URI,可以创新与去数据。

 

  下面是对准成品有关的URI的有建议:

  POST http://www.example.com/products

  用于创造新的产品。

 

  GET|PUT|DELETE http://www.example.com/products/66432

  分别用于读取、更新、删除编号也66432底成品。

 

  那么,如何呢用户创建一个初的订单也?

  一栽方案是:

  POST http://www.example.com/orders

  这种办法得以为此来创造订单,但少相应的用户数据。

  

  为咱们纪念呢用户创建一个订单(注意之间的涉),这个URI可能不敷直观,下面这URI则再度清晰一些:

  POST http://www.example.com/customers/33245/orders

  现在我们了解其是吗编号33245之用户创建一个订单。

 

  那下面是要返回的是什么啊?

  GET http://www.example.com/customers/33245/orders

  可能是一个号吧33245的用户所创建或者持有的订单列表。注意:我们好遮挡对该URI进行DELETE或PUT请求,因为它们的操作对象是一个聚。

 

  继续深入,那下面这个URI的恳求而意味着什么呢?

  POST http://www.example.com/customers/33245/orders/8769/lineitems

  可能是(为编号33245之用户)增加一个码也8769底订单条目。没错!如果以GET方式呼吁是URI,则会回到这个订单的具有条条框框。但是,如果这些章与用户信息无关,我们以见面提供POST
www.example.com/orders/8769/lineitems
这个URI。

  从返回的这些条款来拘禁,指定的资源或会见发生差不多个URIs,所以我们或吧得而供这么一个URI
GET
http://www.example.com/orders/8769
,用来当无知晓用户ID的动静下基于订单ID来查询订单。

 

  更进一步:

  GET http://www.example.com/customers/33245/orders/8769/lineitems/1

  可能独自回去跟个订单被的首先个条文。

  现在您应当明了什么是分层构造了。它们并无是严的条条框框,只是为了保证在你的劳动受到这些强制的组织能还便于受用户所知晓。与有软件开发中的技巧一样,命名是马到成功之严重性。

  

  多看有些API的演示并学会控制这些技能,和而的队友一起来圆而API资源的URIs。这里发生部分APIs的例子:

  • Twitter: https://dev.twitter.com/docs/api
  • Facebook: http://developers.facebook.com/docs/reference/api/
  • LinkedIn: https://developer.linkedin.com/apis

资源命名的反例

  前面我们已讨论过一些正好的资源命名的例证,然而有时有反面的事例也杀有教育意义。下面是一对免太具RESTful风格的资源URIs,看起比乱。这些还是张冠李戴的例证! 

  首先,一些serivices往往用单一的URI来指定服务接口,然后经询问参数来指定HTTP请求的动作。例如,要翻新编号12345之用户信息,带有JSON
body的请或是这样:

  GET
http://api.example.com/services?op=update\_customer&id=12345&format=json

  尽管地方URL中之”services”的是节点是一个名词,但这URL不是自从说的,因为于有的要而言,该URI的层级结构都是同样的。此外,它使用GET作为HTTP动词来实行一个翻新操作,这简直就是是反人类(甚至是惊险的)。

  下面是另外一个翻新用户之操作的例证:

  GET http://api.example.com/update\_customer/12345

  以及它们的一个变种:

  GET http://api.example.com/customers/12345/update

  你晤面时时看于另外开发者的劳务套件中发出多如此的用法。可以看来,这些开发者试图去创造RESTful的资源名称,而且都发矣有前行。但是若还能够分辨出URL中的动词短语。注意,在这URL中我们不欲”update”这个词,因为咱们好依靠HTTP动词来形成操作。下面这URL正好说明了当下或多或少:

  PUT http://api.example.com/customers/12345/update

  这个请而是PUT和”update”,这会针对顾客产生迷惑!这里的”update”指的凡一个资源也?因此,这里我们费些口舌也是冀你能够理解……

复数

  让咱们来讨论一下复数和“单数”的争执…还没听说过?但这种争议确实存在,事实上它可归结为夫问题……

  于您的层级结构面临URI节点是否用让取名吧单数或复数形式为?举个例子,你用来探寻用户资源的URI的命名是否需要像下这样:

  GET http://www.example.com/customer/33245

  或者:

  GET http://www.example.com/customers/33245

  两种方法还不曾问题,但常见咱们且见面挑选使用复数命名,以令你的API
URI在有着的HTTP方法中保持一致。原因是基于这样平等种植考虑:customers是劳动套件中的一个凑,而ID33245之之用户则是者集中的内一个。

  按照这规则,一个用复数形式的多节点的URI会是这样(注意粗体部分):

  GET
http://www.example.com/**customers**/33245/**orders**/8769/**lineitems**/1

  “customers”、“orders”以及“lineitems”这些URI节点都用的是复数形式。

  这表示你的每个根资源就待简单个为主的URL就好了,一个用来创造集合内之资源,另一个用来因标识符获取、更新与去资源。例如,以customers为条例,创建资源可以运用下的URL进行操作:

  POST http://www.example.com/customers

  而读取、更新和去资源,使用下的URL操作:

  GET|PUT|DELETE http://www.example.com/customers/{id}

  正而前提到的,给一定的资源或发差不多个URI,但作为一个最小之整的增删改查功能,利用有限个简单的URI来拍卖就足够了。

  或许你晤面问:是否以聊情况下复数没有意义?嗯,事实上是这么的。当没有汇概念的当儿(此时复数没有意义)。换句话说,当资源就发生一个之气象下,使用单数资源名称也是得的——即一个单纯的资源。例如,如果发一个单一的整布局资源,你可以一个单数名称来代表:

  GET|PUT|DELETE http://www.example.com/configuration

  注意这里少configuration的ID以及HTTP动词POST的用法。假设每个用户发生一个部署来说,那么这URL会是这么:

  GET|PUT|DELETE
http://www.example.com/customers/12345/configuration

  同令人瞩目这里没点名configuration的ID,以及无叫定POST动词的用法。在及时半独例中,可能吧会见有人觉得用POST是有效之。好吧…

 

回到表征

  正而前提到的,RESTful接口支持多资源特色,包括JSON和XML,以及为卷入的JSON和XML。建议JSON作为默认表征,不过服务端应该允许客户端指定其他表征。

  对于客户端请求的风味格式,我们可以当Accept头通过文件扩展名来开展点名,也可经query-string等其他方法来指定。理想图景下,服务端可以支撑所有这些点子。但是,现在正规更赞成于通过类似于文件扩展名的方来开展点名。因此,建议服务端至少用支持下文件扩展名的道,例如“.json”,“.xml”以及她的卷入版本“.wjon”,“.wxml”。

  通过这种措施,在URI中指定返回表征的格式,可以增进URL的可见性。例如,GET
http://www.example.com/customers.xml
以返回customer列表的XML格式的表征。同样,GET
http://www.example.com/customers.json
拿赶回一个JSON格式的特点。这样,即使是在绝基础的客户端(例如“curl”),服务使用起来为会见进一步方便。推荐用这种措施。

  此外,当url中绝非含格式说明时,服务端应该归默认格式的特点(假设为JSON)。例如:

  GET http://www.example.com/customers/12345

  GET http://www.example.com/customers/12345.json

  以上两者返回的ID为12345之customer数据均为JSON格式,这是劳动端的默认格式。

  GET http://www.example.com/customers/12345.xml

  如果服务端支持吧,以上要返回的ID为12345的customer数据为XML格式。如果该服务器不支持XML格式的资源,将回来一个HTTP
404之左。

  使用HTTP
Accept头被大认为是千篇一律种植更优雅的不二法门,并且可HTTP的标准与含义,客户端好通过这种方法来喻HTTP服务端它们可是支撑之数据类型有怎么样。但是,为了以Accept头,服务端要而支持封装和未封装的响应,你不能不兑现自定义之项目——因为这些格式不是正规的品种。这大大加了客户端与服务端的纷繁。请参见RFC
2616底14.1节关于Accept头的详细信息(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1)。使用文件扩展名来指定数量格式是最为简便易行直接的艺术,用最好少之字符就好完成,并且支持脚本操作——无需动HTTP头。

  通常当我们干REST服务,跟XML是毫不相关的。即使服务端支持XML,也几从未人建议于REST中采用XML。XML的科班与公约在REST中未太适用。特别是它们并命名空间还尚未,就重无欠在RESTful服务体系中以了。这只是见面要工作变得又扑朔迷离。所以回来的XML看起还如JSON,它概括好读,没有模式与命名空间的限,换句话来说是任标准的,易于解析。

资源通过链接的但是发现性(HATEOAS续)

  REST指导规范之一(根据合接口规范)是application的状态通过hypertext(超文本)来导。这便是咱司空见惯所说之Hypertext
As The Engine of Application State
(即HATEOAS,用超文本来当应用程序状态机),我们在“REST是什么”同一节约被为涉过。

  根据Roy
Fielding在他的博客中之讲述(http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertextdriven),REST接口中极其重大之局部是超文本的下。此外,他还指出,在受起其它有关的消息之前,一个API应该是可用和而分晓的。也就是说,一个API应当可以透过其链接导航及数的次第组成部分。不建议单独回去纯数据。

  不过当下底业界先驱们连没有经常用这种做法,这反映了HATEOAS仅仅以成熟度模型中的使用率还强。纵观众多的服务体系,它们大多返回重新多的数额,而返的链接却生少(或者没有)。这是违Fielding的REST约定的。Fielding说:“信息之各一个不过寻址单元都携一个地点……查询结果应该展现吗一个分包摘要信息的链接清单,而无是目标往往组。”

  另一方面,简单粗暴地将整链接集合返回会大大影响网络带来富。在事实上状况中,根据所需要的准绳或利用状况,API接口的通信量要因服务器响应中超文本链接所蕴涵的“摘要”数量来抵消。

  同时,充分利用HATEOAS可能会见增加实现之繁杂,并对劳务客户端起强烈的负担,这一定给降低了客户端与服务器端开发人员的生产力。因此,当务之急是只要平衡超链接服务推行及水土保持可用资源中的题目。

  超链接太小化的做法是以无限可怜限度地减小客户端和服务器之间的耦合的又,提高服务端的可用性、可操纵性和可理解性。这些极其小化建议是:通过POST创建资源并打GET请求返回集合,对于发出分页的事态后我们会干。

极端小化链接推荐

  以create的用例中,新建资源的URI(链接)应该于Location响应头中归,且应中心是拖欠的——或者单含有新建资源的ID。

  对于自服务端返回的性状集合,每个表征应该于她的链接集合中带走一个最小的“自身”链接属性。为了方便分页操作,其它的链接可以放在一个独立的链接集合中回到,必要经常好蕴涵“第一页”、“上同一页”、“下一致页”、“最后一页”等消息。

  参照下文链接格式局部的例证获取更多信息。

链接格式

  参照整个链接格式的正规化,建议遵守一些好像Atom、AtomPub或Xlink的品格。JSON-LD也不易,但并无被大规模使用(如果既受用了)。目前业内最广泛的法门是使含有”rel”元素和含有资源总体URI的”href”元素的Atom链接格式,不带有其他身份验证或询问字符串参数。”rel”元素得以蕴涵标准值”alternate”、”related”、”self”、”enclosure”和”via”,还有分页链接的“第一页”、“上同样页”、“下同样页”,“最后一页”。在待常方可于定义并累加应用它。

  一些XML
Atom格式的定义对用JSON格式表示的链接来说是杯水车薪的。例如,METHOD属性对于一个RESTful资源来说是无欲之,因为对此一个加的资源,在颇具支持的HTTP方法(CRUD行为)中,资源的URI都是一致的——所以单独列有这些是没有必要的。

  让咱选一些切实的例证来更验证这或多或少。下面是调用创建新资源的伸手后的应:

  POST http://api.example.com/users

  下面是响应头集合中富含创建新资源的URI的Location部分:

HTTP/1.1 201 CREATED 
Status: 201 
Connection: close 
Content-Type: application/json; charset=utf-8 
Location: http://api.example.com/users/12346

  返回的body可以呢空,或者隐含一个为打包的响应(见下文封装响应)。

  下面的事例通过GET请求获取一个休包含分页的特征集合的JSON响应:

{
  "data": [
    {
      "user_id": "42",
      "name": "Bob",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/42"
        }
      ]
    },
    {
      "user_id": "22",
      "name": "Frank",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/22"
        }
      ]
    },
    {
      "user_id": "125",
      "name": "Sally",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/125"
        }
      ]
    }
  ]
}

  注意,links数组中的各国一样项都含一个对准“自身(self)”的链接。该数组还可能还含有其他关系,如children、parent等。

  最后一个例子是由此GET请求获取一个饱含分页的特色集合的JSON响应(每页显示3件),我们被闹第三页的数:

{
  "data": [
    {
      "user_id": "42",
      "name": "Bob",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/42"
        }
      ]
    },
    {
      "user_id": "22",
      "name": "Frank",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/22"
        }
      ]
    },
    {
      "user_id": "125",
      "name": "Sally",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/125"
        }
      ]
    }
  ],
  "links": [
    {
      "rel": "first",
      "href": "http://api.example.com/users?offset=0&limit=3"
    },
    {
      "rel": "last",
      "href": "http://api.example.com/users?offset=55&limit=3"
    },
    {
      "rel": "previous",
      "href": "http://api.example.com/users?offset=3&limit=3"
    },
    {
      "rel": "next",
      "href": "http://api.example.com/users?offset=9&limit=3"
    }
  ]
}

  在斯例子中,响应中用来分页的links集合中的诸一样宗都含一个对准“自身(self)”的链接。这里可能还会起一些关系到集的旁链接,但还和分页本身无关。简而言之,这里产生三三两两只地方含有links。一个就算是data对象吃所富含的聚集(这个为是接口要赶回给客户端的数表征集合),其中的各个一样件至少要包一个针对性“自身(self)”的links集合;另一个虽说是一个独的对象links,其中包括同分页相关的链接,该有的始末适用于漫天集合。

  对于经过POST请求创建资源的景况,需要在响应头中带有一个涉及新建对象链接的Location

卷入响应

   服务器可以于应中而且返回HTTP状态码和body。有过多JavaScript框架没有管HTTP状态响应码返回给最终之开发者,这频繁会招客户端无法根据状态码来确定具体的一言一行。此外,虽然HTTP规范着发出特别多种响应码,但是频繁只是发生个别客户端会关切这些——通常大家就于乎”success”、”error”或”failture”。因此,将响应内容及应状态码封装于含响应信息的性状着,是发必不可少之。

  OmniTI
实验室有如此一个建议,它深受称之为JSEND响应。更多信息要参见http://labs.omniti.com/labs/jsend。另外一个提案是由Douglas
Crockford提出的,可以查此http://www.json.org/JSONRequest.html。

  这些提案在实践中并不曾了含所有的状。基本上,现在最好的做法是遵照以下属性封装常规(非JSONP)响应:

  • code——包含一个平头类型的HTTP响应状态码。
  • status——包含文本:”success”,”fail”或”error”。HTTP状态响应码在500-599期间也”fail”,在400-499期间吧”error”,其它都为”success”(例如:响应状态码为1XX、2XX及3XX)。
  • message——当状态值为”fail”和”error”时有效,用于展示错误信息。参照国际化(il8n)标准,它可蕴涵信息号或者编码,可以单独含其中一个,或者又寓并因而分隔符隔开。
  • data——包含响应的body。当状态值为”fail”或”error”时,data就含错误原因还是大名称。

  下面是一个返success的包响应:

{
  "code": 200,
  "status": "success",
  "data": {
    "lacksTOS": false,
    "invalidCredentials": false,
    "authToken": "4ee683baa2a3332c3c86026d"
  }
}

  返回error的包裹响应:

{
  "code": 401,
  "status": "error",
  "message": "token is invalid",
  "data": "UnauthorizedException"
}

  这简单独包裹响应对应之XML如下:

<response>
    <code>200</code>
    <status>success</status>
    <data class="AuthenticationResult">
        <lacksTOS>false</lacksTOS>
        <invalidCredentials>false</invalidCredentials>
        <authToken>1.0|idm|idm|4ee683baa2a3332c3c86026d</authToken>
    </data>
</response>

  和:

<response>
    <code>401</code>
    <status>error</status>
    <message>token is invalid</message>
    <data class="string">UnauthorizedException</data>
</response>

处理跨域问题

   我们且听说过关于浏览器的同源策略要同源性需求。它依靠的凡浏览器只能请时正值显示的站点的资源。例如,如果手上正在显示的站点是www.Example1.com,则该站点不可知针对www.Example.com倡议呼吁。显然这会影响站点访问服务器的措施。

  时时有发生零星个受大面积接受的支持跨域请求的章程:JSONP和跨域资源共享(CORS)。JSONP或“填充的JSON”是同一栽采取模式,它提供了一个办法要来自不同域中之服务器的数目。其工作法是从服务器返回任意的JavaScript代码,而未是JSON。客户端的应由JavaScript解析器进行辨析,而休是直接解析JSON数据。另外,CORS是一模一样种植web浏览器的技能专业,它吧web服务器定义了平栽办法,从而允许服务器的资源可以被无同域的网页访问。CORS被看做是JSONP的新式替代品,并且可为所有现代浏览器支持。因此,不建议以JSONP。任何情况下,推荐选择CORS。

支持CORS

  于服务端实现CORS很粗略,只待以殡葬响应时顺便HTTP头,例如: 

Access-Control-Allow-Origin: *

  只有当数是集体使用的状下才会拿造访来源设置为”*”。大多数景象下,Access-Control-Allow-Origin头应该指定哪些域足发起一个CORS请求。只有用跨域访问的URL才装CORS头。

Access-Control-Allow-Origin: http://example.com:8080
http://foo.example.com

  以上Access-Control-Allow-Origin头中,被安装为单独允许给信赖的地带可以看。

Access-Control-Allow-Credentials: true

  只以需要时才以方面是header,因为若用户就报到的话,它会同时发送cookies/sessions。

  这些headers可以经web服务器、代理来开展配置,或者从服务器本身发送。不推荐在服务端实现,因为十分无活络。或者,可以动用方面的亚种植方式,在web服务器上配置一个于是空格分隔的地段的列表。更多关于CORS的情好参照这里:http://enable-cors.org/。

支持JSONP

  JSONP通过应用GET请求避开浏览器的限,从而实现对所有服务的调用。其行事原理是央求方在呼吁的URL上补偿加一个字符串查询参数(例如:jsonp=”jsonp_callback”),其中“jsonp”参数的值是JavaScript函数称为,该函数在产生应返回时拿会让调用。

  由于GET请求中从未包含呼吁求体,JSONP在采取时有着严重的局限性,因此数据要透过字符串查询参数来传递。同样的,为了支持PUT,POST和DELETE方法,HTTP方法必须为透过字符串查询参数来传递,类似_method=POST这种形式。像这么的HTTP方法传送方式是勿推荐下的,这会受服务处于安全风险中。

  JSONP通常以有未支持CORS的老旧浏览器被使用,如果只要改成化支持CORS的,会影响整服务器的架构。或者我们为得以透过代办来促成JSONP。总之,JSONP正在给CORS所代表,我们应当尽可能地动用CORS。

  为了以服务端支持JSONP,在JSONP字符串查询参数传递时,响应必须使实践以下这些操作:

  1. 响应体必须封装成一个参数传递给jsonp中指定的JavaScript函数(例如:jsonp_callback(“<JSON
    response body>”))。
  2. 一味返回HTTP状态码200(OK),并且以忠实的状态作为JSON响应中之一模一样有归。

  另外,响应体中经常要带有响应头。这让JSONP回调方法要基于响应体来确定响应处理方式,因为它自己无法获知真实的响应头和状态值。

  下面的例证是依上述措施封装的一个回到error状态的jsonp(注意:HTTP的响应状态是200):

jsonp_callback("{'code':'404', 'status':'error','headers':[],'message':'resource XYZ not
found','data':'NotFoundException'}")

  成功创办后的响应类似于如此(HTTP的应状态仍是200):

jsonp_callback("{'code':'201', 'status':'error','headers':
[{'Location':'http://www.example.com/customers/12345'}],'data':'12345'}")

 

查询,过滤与分页

  对于大数据集,从带宽的角度来拘禁,限制返回的数据量是好重要的。而自UI处理的角度来拘禁,限制数据量也一如既往至关重要,因为UI通常只能展现大数据汇总之一模一样稍一些数据。在数据集的增长速度不确定的情状下,限制默认返回的数据量是雅有必要之。以Twitter为例,要取有用户的推文(通过个人主页的时空轴),如果无专门指定,请求默认只见面返回20长达记下,尽管系统最多足回来200长条记下。

  除了限制返回的数据量,我们尚待考虑什么对天意据集进行“分页”或下拉滚动操作。创建数量的“页码”,返回大数量列表的早已知道片段,然后标出数据的“前一样页”和“后一致页”——这同样表现给称作分页。此外,我们或也欲指定响应中将包含哪些字段或性质,从而限制返回值的多寡,并且我们意在最后会由此一定值来展开查询操作,并对准回到值进行排序。

  有有限种植重要的计来还要限定查询结果与实施分页操作。首先,我们得建立一个目录方案,它好以页码为导向(请求被一经为出每一样页的记录数及页码),或者因为记录也导向(请求中一直叫有第一漫漫记下及最后一修记下)来确定返回值的起首位置。举个例子,这点儿种办法分别代表:“给起第五页(假设每页有20长达记下)的笔录”,或“给有第100到第120长条的记录”。

  服务端将因运作体制来开展切分。有些UI工具,比如Dojo
JSON会选择模仿HTTP规范行使字节范围。如果服务端支持out of
box(即开箱即用功能),则前端UI工具与后端服务中无需另移,这样使起来会格外有利。

  下文将介绍一栽方法,既能够支持Dojo这样的分页模式(在呼吁求头中受有记录之界定),也能够支持下字符串查询参数。这样一来服务端将转移得更加灵活,既可以用类Dojo一样先进的UI工具集,也足以以简便直接的链接和标签,而不论是需重新为者增加复杂的开工作。但如果服务不直接支持UI功能,可以考虑不要当求求头中让来记录范围。

  要特别指出的凡,我们并无引进以装有服务着运用查询、过滤跟分页操作。并无是持有资源都默认支持这些操作,只有某些特定的资源才支撑。服务及资源的文档应当说明如何接口支持这些纷繁的作用。

结果限制

  “给有第3暨第55长条之笔录”,这种求数据的道和HTTP的字节范围规范更平等,因此我们得以用它来标识Range
header。而“从第2久记下开始,给出最多20长达记下”这种方法更易阅读与喻,因此我们平常会为此字符串查询参数的点子来代表。

  综上所述,推荐既支持使用HTTP Range
header,也支持用字符串查询参数——offset(偏移量)和limit(限制),然后在服务端对响应结果开展限定。注意,如果以支持即半栽方式,那么字符串查询参数的预级要逾Range
header。

  这里你可能会见发生只问题:“这点儿种方式效果相似,但是回到的数额不完全一致。这会无会见于人口歪曲呢?”恩…就是有限个问题。首先使回应的凡,这实在会被人口歪曲。关键是,字符串查询参数看起越清晰易懂,在构建和剖析时更便于。而Range
header则再度多是由机器来以(偏向于底层),它更加符合HTTP使用正规。

  总之,解析Range
header的办事会晤追加复杂度,相应的客户端在构建请求时也得展开一些拍卖。而动单独的limit和offset参数会越加爱理解与构建,并且不欲针对开发人员有再多之要求。

之所以范围标记进行限制

  当用HTTP header而非是字符串查询参数来获得记录之限时,Ranger
header应该通过以下内容来指定范围: 

  Range: items=0-24

  注意记录是从0开始的连年字段,HTTP规范着验证了安采取Range
header来请求字节。也就是说,如果如呼吁数据汇总之首先修记下,范围应当从0开始算从。上述的求将会见回前25独记录,假要数据集中至少有25长长的记下。

  而在服务端,通过检查请求的Range
header来确定该归哪些记录。只要Range
header存在,就会发一个简单的正则表达式(如”items=(\d+)-(\d+)”)对其开展解析,来赢得要找的范围值。

于是字符串查询参数进行限定

  字符串查询参数为用作Range
header的替代选择,它以offset和limit作为参数叫作,其中offset代表要查询的率先久记下编号(与上述的用来范围标记的items第一单数字同样),limit代表记录之顶酷条数。下面的例证返回的结果和上述用范围标记的事例一样:

  GET http://api.example.com/resources?offset=0&limit=25

  Offset参数的值与Range
header中的接近,也是从0开始盘算。Limit参数的价值是回来记录的不过充分数额。当字符串查询参数中莫指定limit时,服务端应当被出一个缺少省之最好老limit值,不过这些参数的下还要在文档中进行认证。

因范围的响应

  对一个基于范围的恳求来说,无论是通过HTTP的Range
header还是经过字符串查询参数,服务端都该来一个Content-Range
header来响应,以标明返回记录的条数和总记录数:

  Content-Range: items 0-24/66

  注意这里的终究记录数(如本例中之66)不是从0开始计的。如果要要数据汇总之尾声几乎长长的记下,Content-Range
header的情节应是这么:

  Content-Range: items 40-65/66

  根据HTTP的正儿八经,如果响应时到底记录数未知或难计算,也足以据此星号(”*”)来取代(如本例中之66)。本例中响应头也只是这样形容:

  *Content-Range: items 40-65/**

  不过只要留意,Dojo或局部旁的UI工具或不支持该符号。

分页

  上述措施通过请求方指定数据集的界定来界定返回结果,从而实现分页功能。上面的例证中一起有66长达记下,如果各国页25长长的记下,要出示第二页数据,Range
header的内容如下:

  Range: items=25-49

  同样,用字符串查询参数表示如下:

  GET …?offset=25&limit=25

  服务端会相应地回一组数据,附带的Content-Range header内容如下:

  Content-Range: 25-49/66

  以多数场面下,这种分页方式都并未问题。但奇迹会发出这种状况,就是一旦回到的笔录数据无法直接表示成多少集中的行号。还有就是是起头数据集的变型快,不断会来新的数量插入到数量集中,这样定会招分页出现问题,一些双重的数目可能会见起于不同之页中。

  按日期排列的数据集(例如Twitter
feed)就是均等栽常见的情事。虽然你或可以针对数据开展分页,但奇迹用”after”或”before”这样的显要字并跟Range
header(或者和字符串查询参数offset和limit)配合来促成分页,看起会愈发从简易亮。

  例如,要落给定时间穿的前20漫漫评论:

  GET
http://www.example.com/remarks/home\_timeline?after=&lt;timestamp&gt; 

  Range: items=0-19

  GET
http://www.example.com/remarks/home\_timeline?before=&lt;timestamp&gt; 

*  Range: items=0-19*

  用字符串查询参数表示为:

  GET
http://www.example.com/remarks/home\_timeline?after=&lt;timestamp&gt;&offset=0&limit=20 

*  GET
http://www.example.com/remarks/home\_timeline?before=&lt;timestamp&gt;&offset=0&limit=20*

  有关以不同情形对时间戳的格式化处理,请参见下文的“日期/时间拍卖”。

  如果要时没有点名要回到的数据范围,服务端返回了相同组默认数据还是限的顶老数据集,那么服务端同时为理应当回去结果中含Content-Range
header来和客户端进行确认。以地方个人主页的年月轴为例,无论客户端是不是指定了Range
header,服务端每次都不过回去20修记下。此时,服务端响应的Content-Range
header应该包含如下内容:

  Content-Range: 0-19/4125

  或 *Content-Range: 0-19/**

结果的过滤和排序

  针对返回结果,还亟需考虑怎样当服务端对数码进行过滤跟排,以及如何依照指定的顺序对子数据进行搜寻。这些操作可以跟分页、结果限制,以及字符串查询参数filter和sort等竞相结合,可以兑现强的数据检索功能。

  再强调平等糟,过滤和排序都是纵横交错的操作,不欲默认提供给所有的资源。下文将介绍如何资源要提供过滤与排序。

过滤

  以本文中,过滤被定义也“通过特定的尺度来确定要使回到的数码,从而减少返回的数额”。如果服务端支持一法完整的比较运算符和复杂性的格相当,过滤操作将变得相当复杂。不过我们普通会采取一些粗略的表达式,如starts-with(以…开始)或contains(包含)来进展匹配,以担保返回数据的完整性。

  于我们开谈论过滤的字符串查询参数之前,必须先知道为什么要利用单个参数而无是基本上独字符串查询参数。从根本上来说是为了减少参数名称的冲。我们曾经发生offsetlimitsort(见下文)参数了。如果可能的语句还见面来jsonpformat标识符,或许还会出afterbefore参数,这些都是于本文遭到干了之字符串查询参数。字符串查询中使的参数越多,就进一步可能致参数名称的冲,而用单个过滤参数则会以闯的可能性降低到最低。

  此外,从服务端也蛮爱就经过单个的filter参数来判定请求方是否要数过滤效果。如果查询需要的复杂度增加,单个参数将还享有灵活性——可以友善树立平等效仿功能一体化的查询语法(详见下文OData注释或看http://www.odata.org)。

  通过引入一组大的、公认的分隔符,用于过滤的表达式可以因充分直观的款式让采用。用这些分隔符来设置过滤查询参数的价值,这些分隔符所创建的参数名/值对能更进一步爱地被服务端解析并提高数据查询的性质。目前都部分分隔符包括用来分隔每个过滤短语的竖线(”|”)和用来分隔参数名叫与价值的对仗冒号(”::”)。这套分隔符足够唯一,并可大多数情况,同时用它来构建的字符串查询参数为越爱懂。下面用用一个简短的事例来介绍其的用法。假设我们怀念如果吃名也“Todd”的用户等发送请求,他们停止在丹佛,有着“Grand
Poobah”之如。用字符串查询参数实现的请求URI如下:

  GET
http://www.example.com/users?filter="name::todd|city::denver|title::grand
poobah”

  双冒号(”::”)分隔符将属于性名和价值分开,这样属性值就能够包含空格——服务端能重爱地由属于性值中剖析出分隔符。

  注意查询参数名/值对遭之性名要和服务端返回的性质名相匹配。

  简单而使得。有关大小写敏感的题目,要基于具体情况来拘禁,但看来,在毫无关心大小写的情景下,过滤效果可生好地运行。若查询参数名/值对受到的属性值未知,你啊得就此星号(”*”)来代替。

  除了简单的表达式和通配符之外,若使开展重复复杂的询问,你不能不使引入运算符。在这种情景下,运算符本身吗是属性值的同一片,能够为服务端解析,而无是成属性名的一律组成部分。当用复杂的query-language-style(查询语言风格)功能时,可参看Open
Data Protocol (OData) Filter System Query
Option说明中之询问概念(详见http://www.odata.org/documentation/uriconventions#FilterSystemQueryOption)。

排序

  排序决定了打服务端返回的记录的各个。也便是指向响应中之几近修记下进行排序。

  同样,我们这里仅仅考虑有比较简单的景。推荐用排序字符串查询参数,它包含了平等组用分隔符分隔的属于性名。具体做法是,默认对每个属性名以升序排列,如果属性名有前缀”-“,则按降序排列。用竖线(”|”)分隔每个属性名,这和前过滤效果中之参数名/值对之做法无异于。

  举个例子,如果我们怀念循用户之姓氏和称展开升序排序,而针对雇佣时间进行降序排序,请求将是这般的:

  GET
http://www.example.com/users?sort=last\_name|first\_name|-hire\_date

  再次强调一下,查询参数名/值对中之性名要和服务端返回的性质名相匹配。此外,由于排序操作比较复杂,我们就对得之资源提供排序功能。如果需要的话也足以当客户端对小之资源集进行排列。

 

劳动版本管理

   坦率地称,一说交本就见面叫人口看非常窘迫,很烦,不极端爱,甚至会为丁认为难受——因为就会增加API的复杂度,并而可能会见指向客户端起局部震慑。因此,在API的设计着要尽量避免多单不等的本子。

  不支持版本,不以版本控制作为糟糕之API设计之仗。如果您在APIs的计划性受到引入版本,这晚早都见面叫您逮狂。由于返回的数目经过JSON来展现,客户端会由于不同的版本要收至不同之性。这样就会在有题材,如由内容本身及认证规则者改变了一个都存在的属性之义。

  当然,我们无能为力避免API可能当好几时段用转移返回数据的格式和情节,而就为以招致消费端的片段转变,我们应当避免进行局部首要的调动。将API进行版本化管理是避这种重大变更的如出一辙栽有效方法。

经过情节商支持版本管理

  以往,版本管理通过URI本身的本号来成功,客户端在伸手的URI中标明要取的资源的版本号。事实上,许多特别商厦如Twitter、Yammer、Facebook、Google等常常在他们之URI里使用版本号。甚至像WSO2这样的API管理工具也会见在她的URLs中求版本号。

  面向REST原则,版本管理技术飞速发展。因为其不分包HTTP规范中置的header,也非支持但当一个新的资源还是概念给引入时才当添加新URI的意——即版本不是表现形式的变型。另一个唱对台戏之说辞是资源URI是勿会见随时间改变的,资源就是资源。

  URI应该能够简单地辨认资源——而未是她的“形状”(状态)。另一个不怕是必须指定响应的格式(表征)。还有局部HTTP
headers:Accept 和 Content-Type。Accept
header允许客户端指定所想或者会支撑的响应的媒体类型(一栽要多种)。Content-Type
header可分别给客户端和劳动端用来指定要或响应的多少格式。

  例如,要赢得一个user的JSON格式的数据:

  #Request:

  GET http://api.example.com/users/12345
  Accept: application/json; version=1

  #Response:

  HTTP/1.1 200 OK
  Content-Type: application/json; version=1

  {“id”:”12345″, “name”:”Joe DiMaggio”}

  现在,我们本着相同资源要版本2底数:

  #Request:

  GET http://api.example.com/users/12345
  Accept: application/json; version=2

  #Response:

  HTTP/1.1 200 OK
  Content-Type: application/json; version=2

  {“id”:”12345″, “firstName”:”Joe”, “lastName”:”DiMaggio”}

  Accept
header被用来代表所要的响应格式(以及示例中之版本号),注意上述两个一律的URI是怎样完成在不同之本子中分辨资源的。或者,如果客户端需要一个XML格式的数码,可以将Accept
header设置也”application/xml”,如果需要的话也堪带动一个指定的版本号。

  由于Accept
header可以让安装为允许多媒体类型,在应请求时,服务器将将响应的Content-Type
header设置为极端匹配配客户端请求内容之项目。更多信息可以参见http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.Html

  例如:

  #Request

  GET http://api.example.com/users/12345

  Accept: application/json; version=1, application/xml; version=1

  上述呼吁中,假设服务器支持JSON
和XML格式的请求,或者个别种都支持,那么将出于服务器来支配最终回哪种类型的数码。但不论是服务器选择啊一样栽,都见面在响应中含有Content-Type
header。

  例如,如果服务器返回application/xml格式的多寡,结果是:

  #Response

  HTTP/1.1 200 OK
  Content-Type: application/xml; version=1

  <user>
    <id>12345</id>
    <name>Joe DiMaggio</name>
  </user>

  为了证明Content-Type在发送数据给服务器时的用途,这里叫来一个用JSON格式创建新用户的事例:

  #Request

  POST http://api.example.com/users
  Content-Type: application/json;version=1

  {“name”:”Marco Polo”}

  或者,调用版本2之接口:

  #Request

  POST http://api.example.com/users
  Content-Type: application/json;version=2

  {“firstName”:”Marco”, “lastName”:”Polo”}

当没有点名版本时,返回什么版本?

  并不需要在每一个呼吁中都指定版本号。由于HTTP
content-negotiation(内容商)遵循类型的“最佳匹配”方式,所以你的API也应按照这或多或少。根据当时同样规格,当客户端从未点名版本时,API应当返回所支撑之极致早版本。

  还是这例子,获取一个user的JSON格式的数目:

  #Request

  GET http://api.example.com/users/12345
  Accept: application/json

  #Response

  HTTP/1.1 200 OK
  Content-Type: application/json; version=1

  {“id”:”12345″, “name”:”Joe DiMaggio”}

  相应地,当为POST方式向服务器发送数据常常,如果服务器支持多个例外版本,而求时同时没点名版本,和上面的例证一样——服务器会将最为小/最早版本的数额包含在body中。为了拓展说明,下面的事例以JSON格式请求一个分包多本资源的服务器,来创造一个新用户(预期会回到版本1):

  #Request

  POST http://api.example.com/users
  Content-Type: application/json

  {“name”:”Marco Polo”}

  #Response

  HTTP/1.1 201 OK
  Content-Type: application/json; version=1
  Location: http://api.example.com/users/12345

  {“id”:”12345″, “name”:”Marco Polo”}

请求不支持之版

  当求一个不支持的版本号时(包含在API生命周期中一度没有的资源版本),API应当返回一个错的HTTP状态码406(表示未为接受)。此外,API还应有返回一个含Content-Type:
application/json的响应体,其中包含一个JSON数组,用于证明该服务器支持之类。

  #Request

  GET http://api.example.com/users/12345
  Content-Type: application/json; version=999

  #Response

  HTTP/1.1 406 NOT ACCEPTABLE 

  Content-Type: application/json

  [“application/json; version=1”, “application/json; version=2”,
“application/xml; version=1”, “application/xml; version=2”]

哟时候理应创建一个初本子?

  API开发被的无数者都见面打破约定,并最后对客户端起部分不良影响。如果您免确定API的改动会带哪些的产物,保险起见最好考虑使用本控制。当你于考虑提供一个初本子是否适合时,或者考虑针对现有的归表征进行修改是否肯定能满足急需并让客户端所受时,有这般几只因素要考虑。

破坏性的改动

  • 更改属性名(例如将”name”改成为”firstName”)
  • 删除属性
  • 变动属性的数据类型(例如将numeric变为string,
    boolean变为bit/numeric,string 变为 datetime等等)
  • 改验证规则
  • 以Atom样式的链接中,修改”rel”的价值
  • 在现有的工作流中引入必要资源
  • 变更资源的定义/意图;概念/意图或资源状态的含义不同于它们原本的意义。例如:
    • 一个content
      type是text/html的资源,之前表示的是独具支持的媒体类型的一个”links”集合,而初的text/html则表示的凡用户输入的“web浏览器表单”。
    • 一个涵盖”endTime”参数的API,对资源”…/users/{id}/exams/{id}”表达的意义是学生在十分时刻付诸试卷,而初的义则是试验的预约完毕时。
  • 经过丰富新的字段来转现有的资源。将少独资源统一为一个并弃用原始的资源。
    • 发出诸如此类简单个资源”…/users/{id}/dropboxBaskets/{id}/messages/{id}”和”…/users/{id}/dropboxBaskets/{id}/messages/{id}/readStatus”。新要求是拿readStatus资源的属性放到单独的message资源面临,并弃用readStatus资源。这将导致messages资源遭受指向readStatus资源的链接给移除。

  虽然上面列有之连无完美,但其深受起了片晤指向客户端起破坏性影响的变迁类型,这时要考虑提供一个初资源要新本子。

非破坏性的修改

  • 每当返的JSON中补充加新属性
  • 添加指向任何资源的”link”
  • 添加content-type支持的初格式
  • 添加content-language支持之新格式
  • 由于API的创立者和买主还设拍卖不同之casing,因此casing的变动无关紧要

版本控制应在什么级别出现?

  建议针对单个的资源开展版本控制。对API的有的变动,如修改工作流,也许要跨越多独资源的版本控制,以这个来防止对客户端起破坏性的震慑。

运用Content-Location来提高响应

  可选。见RDF(Resource Description Framework,即资源描述框架)规范。

带有Content-Type的链接

  Atom风格的链接支持”type”属性。提供足够的消息以便客户端好针对一定的版和内容类型进行调用。

追寻来支持之本子

我该又支持小个本子?

  维护多只不同之本会让工作易得烦、复杂、容易错,而且代价高,对于其余给定的资源,你当支持非超2只本子。

弃用

  Deprecated(弃用)的目的是因此来证明资源对API仍然可用,但当未来会见无存并易得不可用。留神:弃用的时长将由弃用政策决定——这里并没有给有概念。

自哪些告客户端给弃用的资源?

  许多客户端将来走访的资源或在新本子引入后会于废弃掉,因此,他们需要发出一致种植艺术来发现同监察他们之应用程序对委用资源的下。当求一个弃用资源时,API应该正常应,并包含一个布尔品种的自定义Header
“Deprecated”。以下用一个事例来进展验证。

  #Request

  GET http://api.example.com/users/12345
  Accept: application/json
  Content-Type: application/json; version=1

  #Response

  HTTP/1.1 200 OK
  Content-Type: application/json; version=1
  Deprecated: true
  {“id”:”12345”, “name”:”Joe DiMaggio”}

 

日子/时间处理

  如果没有妥善地、一致地处理好日期及日来说,这将变成一个雅累。我们常常会遇到时区的问题,而且由于日期在JSON中凡是因字符串的格式在的,如果无指定统一之格式,那么解析日期也会见是一个题材。

  以接口内部,服务端应该因UTC或GMT时间来储存、处理与缓存时间戳。这将中缓解日期及时空的题材。

Body内容被之日子/时间序列化

  有一个简单的方法好化解这些题目——在字符串中总用同样的格式,包括时间片(带有时区信息)。ISO8601时间格式是一个科学的缓解方案,它应用了了增强的时光格式,包括小时、分钟、秒和秒的小数部分(例如yyyy-MM-dd’T’HH:mm:ss.SSS’Z’)。建议在REST服务之body内容遭(请求和响应均包括)使用ISO8601代表享有的日子格式。

  顺便取一下,对于那些基于JAVA的劳务以来,DateAdapterJ库使用DateAdapter,Iso8601TimepointAdapter和HttpHeaderTimestampAdapter类可以非常容易地剖析和格式化ISO8601日期和日,以及HTTP
1.1
header(RFC1123)格式。可以从https://github.com/tfredrich/DateAdapterJ下载。

  对于那些创建基于浏览器的用户界面来说,ECMAScript5正规一开始就是包含了JavaScript解析和开创ISO8601日期的情节,所以她应当成为我们所说之主流浏览器所遵循的艺术。当然,如果你如果支持那些不能自动解析日期的旧版浏览器,可以动用JavaStript库或正则表达式。这里发生几乎个好分析及创建ISO8601时间之JavaStript库:

  http://momentjs.com/

  http://www.datejs.com/

HTTP Headers中的日子/时间序列化

  然而上述提议才适用于HTTP请求或响应内容中的JSON和XML内容,HTTP规范对HTTP
headers使用任何一样种不同的格式。在被RFC1123又给之RFC822中指出,该格式包括了各种日期、时间及date-time格式。不过,建议始终用时间戳格式,在公的request
headers中它看起如这样:

  Sun, 06 Nov 1994 08:49:37 GMT

  不过,这种格式没有设想毫秒或者秒的十进制小数。Java的SimpleDataFormat的格式串是:”EEE,
dd MMM yyyy HH:mm:ss ‘GMT'”。

 

保安服务的安全

  Authentication(身份验证)指的凡确认给定的伸手是自从服务一度知晓之某(或某某系统)发出的,且请求者是外自己所声明的很人。Authentication是以证实请求者的真实性身份,而authorization(授权)是为验证请求者有权力去实践于呼吁的操作。

  本质上,这个历程是这么的:

  1. 客户端发起一个请,将authentication的token(身份认证令牌)包含在X-Authentication
    header中,或者将token叠加以请的查询串参数中。
  2. 服务器对authorization
    token(授权令牌)进行检讨,并进行验证(有效且非过),并因令牌内容分析或者加载认证中心。
  3. 服务器调用授权服务,提供证明中心、被请资源与必备之操作许可。
  4. 倘授权通过了,服务器将会晤持续健康运作。

  上面第三步的开可能会见于坏,但是要如果存在一个只是缓存的权杖控制列表(ACL),那么当有远程请求前,可以当本地创建一个授权客户端来缓存最新的ACLs。

身份验证

  时最好之做法是用OAuth身份验证。强烈推荐OAuth2,不过它依旧处在草案状态。或者选择OAuth1,它了可以胜任。在好几情况下也堪挑选3-Legged
OAuth。更多关于OAuth的正规好查阅此http://oauth.net/documentation/spec/。

  OpenID是一个叠加选择。不过建议以OpenID作为一个增大的身份验证选项,以OAuth为主。更多关于OpenID的标准好查看此http://openid.net/developers/specs/。

传输安全

  所有的说明都该以SSL。OAuth2需要授权服务器和access
token(访问令牌)来以TLS(安全传输层协议)。

  以HTTP和HTTPS之间切换会带来安全隐患,最好之做法是拥有简报默认都利用TLS。

授权

  对劳动之授权和针对另应用程序的授权一样,没有任何区别。它根据这样一个题材:“主体是不是对准加的资源出求的许可?”这里给出了简短的老三件数据(主体,资源和批准),因此非常易构造一个支撑这种概念的授权服务。其中核心是给予以资源访问许可的人数要系。使用这些相似概念,就可以吗各个一个主题构建一个缓存访问控制列表(ALC)。

应用程序安全

  对RESTful服务来说,开发一个平安之web应用适用同的准。

  • 于服务器上说明所有输入。接受“已解”的不易的输入并驳回错误的输入。
  • 防止SQL和NoSQL注入。
  • 运library如微软的Anti-XSS或OWASP的AntiSammy来针对输出的数额开展编码。
  • 拿消息的尺寸限制于确定的字段长度内。
  • 劳动应该就展示一般的错误信息。
  • 考虑工作逻辑攻击。例如,攻击者可超越了多步骤的订购流程来预订产品而任由需输入信用卡信息也?
  • 针对可疑之移动记录日志。

  RESTful安全用留意的地方:

  • 证明数据的JSON和XML格式。
  • HTTP动词应该吃限以同意的点子吃。例如,GET请求不克去除一个实体。GET用来读取实体而DELETE用来删除实体。
  • 瞩目race
    conditions(竞争原则——由于个别个或多单过程竞争下不可知于以做客的资源,使得这些过程产生或为时间及推进的次序由一旦起问题)。

  API网关可用于监视、限制与控制对API的拜会。以下内容可由网关或RESTful服务实现。

  • 监视API的采取状况,并询问什么活动是正常的,哪些是非正常的。
  • 克API的利用,使恶意用户不可知止住少一个API服务(DOS攻击),并且产生力量阻止恶意之IP地址。
  • 以API密钥存储于加密的平安密钥库中。

 

缓存和可伸缩性

  通过以网层级消除通过远距离调用来赢得请求的数额,缓存提高了系的而扩展性。服务通过以应中设置headers来加强缓存的能力。遗憾之是,HTTP
1.0被以及缓存相关的headers与HTTP
1.1例外,因此服务器如果而支持有限种版本。下表给起了GET请求而支持缓存所不可不的无限少headers集合,并吃有了适龄的叙说。

HTTP Header

描述

示例

Date

一呼百应返回的日期及时间(RFC1123格式)。

Date: Sun, 06 Nov 1994 08:49:37 GMT

Cache-Control

应可于缓存的顶酷秒数(最酷age值)。如果响应不支持缓存,值为no-cache。

Cache-Control: 360

Cache-Control: no-cache

Expires

万一为闹了最大age值,该日戳(RFC1123格式)表示的是应过期的流年,也便是Date(例如当前日期)加上最特别age值。如果响应不支持缓存,该headers不在。

Expires: Sun, 06 Nov 1994 08:49:37 GMT

Pragma

当Cache-Control为no-cache时,该header的值也让装置为no-cahche。否则,不存在。

Pragma: no-cache

Last-Modified

资源本身最后让修改的时日戳(RFC1123格式)。

Last-Modified: Sun, 06 Nov1994 08:49:37 GMT

  为了简化,这里选出一个应中之headers集合的事例。这是一个简单的对资源开展GET请求的响应,缓存时长为同一天(24小时):

  Cache-Control: 86400
  Date: Wed, 29 Feb 2012 23:01:10 GMT
  Last-Modified: Mon, 28 Feb 2011 13:10:14 GMT
  Expires: Thu, 01 Mar 2012 23:01:10 GMT

  下面是一个近似的例子,不过缓存被全然禁用:

  Cache-Control: no-cache
  Pragma: no-cache

ETag Header

  ETag
header对于证明缓存数据的初老程度深有因此,同时为推动条件的读取和翻新操作(分别吗GET和PUT)。它的值是一个任意字符串,用来代表回到数据的版本。不过,对于返回数据的不同格式,它也可以不同——JSON格式响应的ETag与同样资源XML格式响应的ETag会不同。ETag
header的值好像带有格式的底层域对象的哈希表(例如Java中的Obeject.hashcode())一样简单。建议也每个GET(读)操作返回一个ETag
header。另外,确保用对引号包含ETag的价,例如:

  ETag: “686897696a7c876b7e”

 

HTTP状态码(前10)

  以下是由于RESTful服务要API返回的尽常用之HTTP状态码,以及一些关于她广泛用法的简练说明。其它HTTP状态码不太经常用,它们还是更破例,要么更尖端。大多数劳务套件只支持这些常用的状态码,甚至光支持中的均等有的,并且其还能够正常工作。

  200 (OK) —— 通常的打响状态。表示成功之最好普遍代码。

  201 (CREATED) ——(通过POST或PUT)创建成功。通过安装Location
header来含有一个针对最新创建的资源的链接。

  204 (NO CONTENT)
—— 封装了之应没有下,或body中从不其他内容常常(如DELETE),使用该状态。

  304 (NOT MODIFIED)
—— 用于产生标准的GET调用的应,以调减带宽的应用。
如果使用该状态,那么要也GET调用设置Date、Content-Location和ETag
headers。不带有响应体。

  400 (BAD REQUEST)
—— 用于实践要时或者惹无效状态的一般错误代码。如域名无效错误、数据丢失等。

  401 (UNAUTHORIZED)
—— 用于缺少认证token或说明token无效的错误代码。

  403 (FORBIDDEN)
—— 未授权的用户执行操作,没有权限访问资源,或者出于一些原因资源不可用(如时间限定等),使用该错误码。

  404 (NOT FOUND)
—— 无论资源存不有,无论是否发生401、403的界定,当求的资源找不交经常,出于安全因素考虑,服务器都得采用该错误码来掩饰。

  409 (CONFLICT)
—— 每当执行要或会见滋生资源撞常常采取。例如,存在更的实业,当不支持级联删除时去除根对象。

  500 (INTERNAL SERVER ERROR)
—— 当服务器抛来非常时,捕捉到之形似错误。

 

叠加资源

书籍

  REST API Design Rulebook,Mark Masse, 2011, O’Reilly Media, Inc.

  RESTful Web Services, Leonard Richardson and Sam Ruby, 2008,
O’Reilly Media, Inc.

*  RESTful Web Services Cookbook, Subbu Allamaraju, 2010, O’Reilly
Media, Inc.*

  REST in Practice: Hypermedia and Systems Architecture, Jim Webber,
et al., 2010, O’Reilly Media, Inc.

  APIs: A Strategy Guide, Daniel Jacobson; Greg Brail; Dan Woods,
2011, O’Reilly Media, Inc.

网站

  http://www.restapitutorial.com
http://www.toddfredrich.com
  http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
  http://www.json.org/
https://github.com/tfredrich/DateAdapterJ
  http://openid.net/developers/specs/
  http://oauth.net/documentation/spec/
  http://www.json.org/JSONRequest.html
http://labs.omniti.com/labs/jsend
  http://enable-cors.org/
  http://www.odata.org/documentation/uri-conventions#FilterSystemQueryOption
  http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
  https://developer.linkedin.com/apis
  http://developers.facebook.com/docs/reference/api/
  https://dev.twitter.com/docs/api
http://momentjs.com/
  http://www.datejs.com/

 

当原本翻译的基础及经过改动:http://blog.csdn.net/huayuqa/article/details/62237010

英文原稿下载:RESTful Best Practices-v1
2.pdf

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图