RESTful服务至上实践。RESTful服务至上实践。

本文主要读者

正文主要读者

引言

引言

REST是什么

REST是什么

  联合接口

  联接口

    冲资源

    冲资源

    通过特色来操作资源

    经过特征来操作资源

    自打描述的音讯

    从今描述的消息

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

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

  无状态

  无状态

  可缓存

  可缓存

  C-S架构

  C-S架构

  分系统

  旁系统

  按需编码(可选)

  按需编码(可选)

REST快速提示

REST快速提示

  使用HTTP动词表示有含义

  应用HTTP动词表示有意义

  成立之资源名

  理所当然之资源名

  XML和JSON

  XML和JSON

  创造适当粒度的资源

  缔造适当粒度的资源

  设想连通性

  考虑连通性

定义

定义

  幂等性

  幂等性

  安全

  安全

HTTP动词

HTTP动词

  GET

  GET

  PUT

  PUT

  POST

  POST

  PUT和POST的创办于

  PUT和POST的创造于

  DELETE

  DELETE

资源命名

资源命名

  资源URI示例

  资源URI示例

  资源命名的反例

  资源命名的反例

  复数

  复数

回表征

回表征

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

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

    无限小化链接推荐

    最好小化链接推荐

    链接格式

    链接格式

  卷入响应

  装进响应

  处理跨域问题

  拍卖跨域问题

    支持CORS

    支持CORS

    支持JSONP

    支持JSONP

询问,过滤跟分页

查询,过滤和分页

  结果限制

  结果限制

    从而范围标记进行界定

    故范围标记进行限制

    据此字符串查询参数进行限

    之所以字符串查询参数进行限定

    依据范围的响应

    因范围之应

  分页

  分页

  结果的过滤跟排序

  结果的过滤与排序

    过滤

    过滤

    排序

    排序

劳务版本管理

劳动版本管理

  透过内容商支持版本管理

  通过内容商支持版本管理

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

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

  请不支持之版

  呼吁不支持的本子

  好家伙时候该创建一个初本子?

  嘿时候该创建一个初本子?

    破坏性的改动

    破坏性的改动

    非破坏性的改

    非破坏性的修改

  版本控制应于啊级别出现?

  版本控制应在啊级别出现?

  使用Content-Location来提高响应

  应用Content-Location来增进响应

  带有Content-Type的链接

  带有Content-Type的链接

  检索来支持的本

  找寻来支持的版本

    本人应当又支持小只版?

    自己应该而且支持小个本子?

    弃用

    弃用

    本身怎样告客户端给弃用的资源?

    我什么告客户端给弃用的资源?

日子/时间处理

日期/时间处理

  Body内容遭的日子/时间序列化

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

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

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

护服务之平安

保障服务的安康

  身份验证

  身份验证

  传安全

  传输安全

  授权

  授权

  应用程序安全

  应用程序安全

缓存和可伸缩性

缓存和可伸缩性

  ETag Header

  ETag Header

HTTP状态码(前10)

HTTP状态码(前10)

外加资源

外加资源

  书籍

  书籍

  网站

  网站

 

 

正文主要读者

  该最佳实践文档适用于对RESTful
Web服务感兴趣的开发人员,该服务呢过多个劳务的机件提供了比较高之可靠性与一致性。按照本文的点拨,可快捷、广泛、公开地也内外部客户使用。

  本文中之点拨原则一致适用于工程师等,他们想使这些根据最佳实践标准开发之劳务。虽然她们更是关心缓存、代理规则、监听与平安等有关地方,但是该文档能作为同一卖包含所有类型服务之总指南。

  另外,通过由这些点标准,管理人员了解及创建公共的、提供高稳定的劳动所用花的着力,他们为不过从中受益。

 

正文主要读者

  该最佳实践文档适用于对RESTful
Web服务感兴趣的开发人员,该服务呢过多独服务的组件提供了于高之可靠性与一致性。按照本文的点拨,可速、广泛、公开地为内外部客户采用。

  本文中的指点原则一致适用于工程师等,他们期望下这些根据最佳实践标准开发之劳务。虽然他们进一步关心缓存、代理规则、监听与平安等相关方面,但是该文档能作为同样客包含所有项目服务的总指南。

  另外,通过自这些点规范,管理人员了解及创造公共的、提供高稳定性的劳动所待花费的鼎力,他们也可是从中受益。

 

引言

  现今曾经发恢宏有关RESTful
Web服务至上实践的相关资料(详见本文最后之相干文献有)。由于撰文的时间不同,许多资料被的内容是矛盾的。此外,想使透过翻文献来了解这种服务之进化是无顶长的。为了了解RESTful这等同概念,至少要查阅三顶五随有关文献,而本文将能够拉你加快这同样进程——摒弃多余的座谈,最大化地提炼出REST的极品实践以及标准。

  与其说REST是均等效仿标准,REST更如是相同栽标准的集。除了六独重点的条件外就是从来不任何的正式了。实际上,虽然有所谓的“最佳实践”和正式,但这些事物还与宗教斗争一样,在不断地演变。

  本文围绕REST的科普问题提出了意以及仿食谱式的议论,并通过介绍部分略的背景知识对创建真实地下的先生产环境遭受一致的REST服务提供文化。本文收集了来自外渠道的信息,经历过一次次之失败后不断改进。

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

  第一局部概述REST的意义、设计则与她的例外的远在。第二片段点数了有些聊贴士来记忆REST的劳动理念。之后的一些则会再也透地啊web服务创建人员提供部分细节的支持及讨论,来促成一个能明白展示在生养环境被的高质量REST服务。

 

引言

  现今就发出恢宏有关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架构
  • 分系统
  • 按需编码

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

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编码则要因请求与服务器实现的细节来决定。

  基于资源

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

  通过特征来操作资源

  当客户端收到包含元数据的资源的特征时,在闹权力的情状下,客户端都控制的十足的音讯,可以对劳务端的资源拓展删改。

  通过特色来操作资源

  当客户端收到包含元数据的资源的特点时,在生权力的景况下,客户端都控制的足的信息,可以针对劳动端的资源开展删改。

  自描述的音信

  每条消息还带有足够的数码用于确认信息该怎么处理。例如要由网络媒体类型(已掌握之若MIME类型)来确认要调用哪个解析器。响应同样也表明了它们的缓存能力。

  自描述的信

  每条信息都蕴含足够的多寡用于确认消息该如何处理。例如要出于网络媒体类型(已领略的要MIME类型)来认可要调用哪个解析器。响应同样为标志了它们的缓存能力。

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

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

  除了上述内容他,HATEOS也表示,必要之时刻链接也不过给含有在回到的body(或头部)中,以提供URI来寻觅对象自我还是关系对象。下文将对准这展开再次详实的阐释。

  统一接口是每个REST服务统筹时之画龙点睛准则。

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

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

  除了上述情节他,HATEOS也象征,必要的时刻链接也可给含有在回去的body(或头部)中,以供URI来寻觅对象自我还是涉嫌对象。下文将对斯展开双重详实的论述。

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

无状态

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

  从事我们当即同样业的大部人犹习惯使用容器来编程,容器中产生一个“会话”的定义,用于在差不多只HTTP请求下保持状态。在REST中,如果要是以差不多个请求下保持用户状态,客户端必须概括客户端的持有消息来就请求,必要时再也发送请求。自从服务端不需要保持、更新或传递会话状态后,无状态性得到了再次要命之延展。此外,负载均衡器无需担心和任状态系统内的对话。

  所以状态与资源中发生什么差异?服务器对状态,或者说是应用状态,所关心的接触是于此时此刻对话或请被使形成请求所用的数据。而资源,或者说是资源状态,则是概念了资源特点的数目,例如存储在数据库中之数码。由此可见,应用状态是凡趁客户端以及呼吁的变动而改变之多寡。相反,资源状态对于发出请求的客户端的话是不转移的。

  于网采用的之一一样一定岗位及张一个赶回按钮,是因它们希望您可知随自然的依次来操作为?其实是以她违反了无状态的尺度。有众多未听命无状态原则的案例,例如3-Legged
OAuth,API调用速度限制等。但要么要硬着头皮保证服务器被未欲以差不多个请求下保持利用状态。

无状态

  正如REST是REpresentational State
Transfer的缩写,无状态不行重点。本质上,这标志了处理要所待的状态已包含在求我里,也生或是URI的一模一样组成部分、查询串参数、body或头部。URI能够唯一标识每个资源,body中呢蕴藏了资源的转态(或转态变更情况)。之后,服务器将拓展处理,将相关的状态或资源通过头部、状态及响应body传递让客户端。

  从事我们当即等同行之大部丁犹习惯用容器来编程,容器中出一个“会话”的定义,用于在差不多只HTTP请求下保持状态。在REST中,如果要以差不多个请求下保持用户状态,客户端必须概括客户端的富有消息来就请求,必要常常再也发送请求。自从服务端不需保障、更新或传递会话状态后,无状态性得到了再可怜的延展。此外,负载均衡器无需担心和管状态系统中的对话。

  所以状态和资源间有什么差异?服务器对状态,或者说是应用状态,所关心的点是于眼前对话或要被如形成请求所欲的数码。而资源,或者说是资源状态,则是概念了资源特色的多寡,例如存储于数据库中之数量。由此可见,应用状态是是乘客户端和伸手的改变如果改变的数目。相反,资源状态对于发出请求的客户端的话是无变换的。

  在网络下之某平一定岗位上布置一个归按钮,是为她仰望你能按自然的各个来操作也?其实是坐它违反了不管状态的尺码。有成千上万非守无状态原则的案例,例如3-Legged
OAuth,API调用速度限制等。但要么如尽可能保证服务器中无需以差不多只请求下保持利用状态。

可缓存

  于万维网上,客户端可缓存页面的响应内容。因此应都应隐式或显式的定义为可缓存的,若不足缓存则使避免客户端在屡次呼吁后为此老数据或者污染数据来响应。管理得当的苏存会部分地要全地除了客户端和服务端之间的互动,进一步改善性与延展性。

可缓存

  以万维网上,客户端可缓存页面的应内容。因此应都答应隐式或显式的概念也而缓存的,若不足缓存则要避免客户端在三番五次请后之所以旧数据要污染数据来响应。管理得当的休息存会部分地还是全地除了客户端以及服务端之间的相,进一步改进性和延展性。

C-S架构

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

C-S架构

  统一接口使得客户端与服务端相互分开。关注分离意味什么?打只假设,客户端不需仓储数据,数据都养在服务端内部,这样让客户端代码的可移植性得到了晋级;而服务端不需要考虑用户接口及用户状态,这样一来服务端将更简约好拓展。只要接口不移,服务端和客户端好独立地开展研发与替换。

分段系统

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

子系统

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

按需编码(可选)

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

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

  提示:REST架构中的筹划则遭到,只有按照需要编码为可选项。如果某服务违反了另外随意一起则,严格意思上不能够称之为RESTful风格。

 

按需编码(可选)

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

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

  提示:REST架构中的计划则遭到,只有按需要编码为而选取项。如果某个服务违反了另随意一起则,严格意思上不克称之为RESTful风格。

 

REST快速提示

  (根据地方提到的六单原则)不管在技术上是匪是RESTful的,这里出部分看似REST概念的建议。遵循其,可以兑现还好、更使得的劳务:

REST快速提示

  (根据地方提到的六个条件)不管在技术上是匪是RESTful的,这里产生有好像REST概念的建议。遵循它,可以实现还好、更实惠之劳动:

下HTTP动词表示有意思

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

使HTTP动词表示有意思

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

合理的资源名

  合理的资源名称或者路径(如/posts/23只要未是/api?type=posts&id=23)可以还强烈一个告的目的。使用URL查询串来过滤数据是颇好的章程,但非该用于固定资源名称。

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

理所当然之资源名

  合理的资源名称或路径(如/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作为响应。在她于全然淘汰之前,这是终极一个但给得之地方。

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(增删查改)功能,可以假设资源的创始变得再便于。随后,你可创造这些根据用例和压缩通信量的资源。

创立适当粒度的资源

  同开始,系统受效仿底层应用程序域或数据库架构的API更易给创造。最终,你晤面想将这些劳务都整合到一起——利用基本上件底层资源减少通信量。在创建独立的资源之后重新创更怪粒度的资源,比由再特别的一块集中创建于生粒度的资源更加容易有。从一些有点之易定义的资源开始,创建CRUD(增删查改)功能,可以要资源的创立变得再便于。随后,你可以创建这些根据用例和压缩通信量的资源。

考虑连通性

  REST的法则之一即是连通性——通过超媒体链接实现。当当响应中回到链接时,api变的复有从描述性,而于没她常服务端依然可用。至少,接口本身可以吧客户端提供怎样寻找数据的参考。此外,在通过POST方法创建资源时,还得以头位置包含一个链接。对于响应中支持分页的集聚,”first”、
“last”、”next”、和”prev”链接至少是大实用之。

 

设想连通性

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

 

定义

定义

幂等性

  不要打字面意思来了解啊是幂等性,恰恰相反,这与某些功能紊乱的世界无关。下面是来自维基百科的诠释:

当计算机对中,术语幂当用于更全面地叙述一个操作,一不行或累执该操作有的结果是一样的。根据使用的上下文,这也许来两样之意思。例如,在术要子例程调用具有副作用的气象下,意味着在首先调用之后被改动的状态吧维持不转换。

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

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

幂等性

  不要打字面意思来掌握什么是幂等性,恰恰相反,这跟某些职能紊乱的园地无关。下面是缘于维基百科的解释:

每当微机科学中,术语幂相当用于更完美地讲述一个操作,一蹩脚还是数执该操作有的结果是平等的。根据使用之上下文,这或者产生不同的意义。例如,在点子或者子例程调用拥有副作用的状下,意味着在率先调用之后吃涂改的状态呢保持不更换。

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

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

安全

  来自维基百科:

部分智(例如GET、HEAD、OPTIONS和TRACE)被定义也安的法,这代表它仅仅吃用来信息搜索,而不克转服务器的状态。换句话说,它们不会见出副作用,除了相对来说无害的熏陶而日志、缓存、横幅广告要计数服务等。任意的GET请求,不考虑动用状态的上下文,都叫看是平安之。

  总之,安全意味着调用的法无会见招副作用。因此,客户端好屡屡使用安全之乞求而不用担心对服务端产生任何副作用。这象征服务端必须遵GET、HEAD、OPTIONS和TRACE操作的安全概念。否则,除了对消费端产生模糊外,它还见面招致Web缓存,搜索引擎以及其它活动代理的问题——这将于服务器上产生意想不到的产物。

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

  安全之措施为实现啊单读操作。然而,安全并无意味着服务器必须每次都回来相同之应。

 

安全

  来自维基百科:

部分方(例如GET、HEAD、OPTIONS和TRACE)被定义也安全的道,这意味它们就被用于信息寻找,而无能够改服务器的状态。换句话说,它们不见面产生副作用,除了相对来说无害的熏陶而日志、缓存、横幅广告要计数服务等。任意的GET请求,不考虑动用状态的上下文,都于当是安的。

  总之,安全意味着调用的艺术不会见惹副作用。因此,客户端好数使用安全之呼吁而非用担心对服务端产生任何副作用。这代表服务端必须遵从GET、HEAD、OPTIONS和TRACE操作的安全概念。否则,除了对消费端产生模糊外,它还会见促成Web缓存,搜索引擎以及任何活动代理的题材——这将于服务器上发意想不到的结局。

  根据定义,安全操作是幂等的,因为她于服务器上生相同的结果。

  安全的点子吃实现呢单独读操作。然而,安全并无意味着服务器必须每次都回去相同之应。

 

HTTP动词

  Http动词主要以“统一接口”规则,并提供给咱们相应之根据名词的资源的动作。最要要最好常用之http动词(或者叫做方法,这样叫可能更恰当些)有POST、GET、PUT和DELETE。这些分别指向应于创建、读取、更新与去(CRUD)操作。也发很多其它的动词,但是采取效率比较没有。在这些使用于少之计被,OPTIONS和HEAD往往使得重新多。

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暴露不安全之操作——它应该永远都不可知修改服务器上的旁资源。

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。

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请求很可能会见导致创建两单包含相同信息之资源。

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请求来创造新的资源。

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(未找到)。

 

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:

资源命名

  除了当地用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

资源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”指的是一个资源为?因此,这里我们费些口舌也是望你可知知道……

资源命名的反例

  前面我们曾讨论过部分适龄的资源命名的事例,然而有时有反面的例子也生有教育意义。下面是局部勿顶有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是行之有效之。好吧…

 

复数

  让咱们来讨论一下复数和“单数”的争辩…还没听说过?但这种争议确实是,事实上它们好归纳为是问题……

  于您的层级结构面临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,它大概容易读,没有模式及命名空间的界定,换句话来说是管正式的,易于解析。

返回表征

  正使前方提到的,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请求返回集合,对于有分页的情后我们见面提到。

资源通过链接的可是发现性(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。

  对于自服务端返回的特色集合,每个表征应该以它的链接集合中携带一个最好小的“自身”链接属性。为了有利于分页操作,其它的链接可以在一个单独的链接集合中归,必要时好蕴涵“第一页”、“上一致页”、“下一致页”、“最后一页”等信息。

  参照下文链接格式有的例子获取更多信息。

最小化链接推荐

  在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

链接格式

  参照整个链接格式的标准,建议遵守一些类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>

包裹响应

   服务器可以以应中还要返回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。

拍卖跨域问题

   我们且闻讯了有关浏览器的同源策略要同源性需求。它借助的是浏览器只能请时正值显示的站点的资源。例如,如果手上正显示的站点是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/。

支持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'}")

 

支持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功能,可以设想不要以恳求求头中为起记录范围。

  要专门指出的凡,我们连无推荐在富有服务遭遇应用查询、过滤和分页操作。并无是拥有资源都默认支持这些操作,只有少数特定的资源才支撑。服务和资源的文档应当说明什么接口支持这些扑朔迷离的效力。

查询,过滤和分页

  对于大数据集,从带宽的角度来拘禁,限制返回的数据量是不行重要的。而由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参数会越加爱理解与构建,并且不欲针对开发人员有更多之要求。

结果限制

  “给出第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+)”)对那进展辨析,来取得要寻找的范围值。

于是范围标记进行界定

  当用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值,不过这些参数的使用还用以文档中开展认证。

之所以字符串查询参数进行限定

  字符串查询参数为视作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工具或未支持该符号。

根据范围之应

  对一个冲范围之呼吁来说,无论是通过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/**

分页

  上述方法通过请求方指定数据集的范围来界定返回结果,从而实现分页功能。上面的例证中累计发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等互动结合,可以实现强的数据检索功能。

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

结果的过滤跟排序

  针对返回结果,还需考虑什么当服务端对数码进行过滤跟排,以及哪些按照指定的逐一对子数据进行搜。这些操作可以同分页、结果限制,以及字符串查询参数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)。

过滤

  于本文中,过滤被定义为“通过特定的规则来确定要使赶回的数量,从而减少返回的数”。如果服务端支持一模拟完整的于运算符和错综复杂的尺度配合,过滤操作以转移得一定复杂。不过我们司空见惯会动一些简单的表达式,如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

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

 

排序

  排序决定了由服务端返回的笔录之相继。也便是针对性响应中之大多久记下进行排序。

  同样,我们这边就考虑有比较简单的情况。推荐使用排序字符串查询参数,它富含了一致组用分隔符分隔的属于性名。具体做法是,默认对每个属性名以升序排列,如果属性名有前缀”-“,则随降序排列。用竖线(”|”)分隔每个属性名,这同前边过滤效果受到之参数名/值对之做法一样。

  举个例子,如果我们怀念以用户之姓氏和名进行升序排序,而针对性雇佣时间进行降序排序,请求将是如此的:

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

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

 

劳版本管理

   坦率地说道,一说到本就会见于人以为特别艰难,很辛苦,不极端容易,甚至会见被丁觉着难受——因为及时会增多API的复杂度,并还要可能会见指向客户端有有震慑。因此,在API的规划着设尽量避免多单不同的本子。

  不支持版本,不以版本控制作为糟糕之API设计的依靠。如果您以APIs的筹划受到引入版本,这晚早都见面给你逮狂。由于返回的数量通过JSON来展现,客户端会由于不同的本要收至不同之习性。这样尽管会是有的题材,如由内容我及认证规则者改变了一个既在的习性之意思。

  当然,我们无能为力避免API可能在少数时段需要变更返回数据的格式和情节,而这吗以促成消费端的组成部分浮动,我们当避免进行局部要的调动。将API进行版本化管理是免这种根本转变的一样种植有效方式。

劳动版本管理

   坦率地说话,一说交本就见面为人当十分艰难,很辛苦,不太容易,甚至会受人以为难受——因为就会加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”}

透过内容商支持版本管理

  以往,版本管理通过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”}

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

  并不需要在每一个呼吁被还指定版本号。由于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应当返回一个左的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的改会带动怎样的结果,保险起见最好考虑采用本控制。当你在设想提供一个初本子是否恰当时,或者考虑针对现有的回表征进行改动是否定能满足急需并吃客户端所接受时,有这样几独元素而考虑。

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

  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资源的链接给移除。

  虽然上面列有的并无周全,但其让出了部分会面指向客户端有破坏性影响的更动类型,这时需要考虑提供一个初资源还是新本子。

破坏性的改

  • 更改属性名(例如将”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的浮动无关紧要

非破坏性的修改

  • 当回来的JSON中上加新属性
  • 长指向任何资源的”link”
  • 添加content-type支持之新格式
  • 添加content-language支持的初格式
  • 出于API的缔造者和顾客都要处理不同之casing,因此casing的变型无关紧要

版本控制应在啊级别出现?

  建议针对单个的资源开展版本控制。对API的部分改变,如修改工作流,也许如果跳多只资源的版本控制,以这个来预防对客户端起破坏性的震慑。

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

  建议针对性单个的资源进行版本控制。对API的一些改成,如修改工作流,也许要超越多独资源的版本控制,以这来防护对客户端起破坏性的震慑。

采用Content-Location来增长响应

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

动用Content-Location来提高响应

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

带有Content-Type的链接

  Atom风格的链接支持”type”属性。提供足够的音信以便客户端好针对一定的版与情节类型进行调用。

带有Content-Type的链接

  Atom风格的链接支持”type”属性。提供足够的音以便客户端好针对特定的本子与情节类型进行调用。

查找有支持的版

招来来支持的版本

自我应当同时支持小个版本?

  维护多单例外的本子会叫劳作换得烦、复杂、容易出错,而且代价高,对于其他给定的资源,你应当支持不越2只本子。

我该又支持小个版本?

  维护多只例外之本会让工作换得烦、复杂、容易错,而且代价高,对于其他给定的资源,你应该支持不超过2独本子。

弃用

  Deprecated(弃用)的目的是故来证实资源对API仍然可用,但在明天见面无在并转移得不可用。只顾:弃用的时长将由弃用政策决定——这里并没受起概念。

弃用

  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”}

 

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

  许多客户端将来作客的资源或当新本子引入后会见给废弃掉,因此,他们用来一致种方法来发现跟监控他们之应用程序对委用资源的使用。当呼吁一个弃用资源时,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时间来囤积、处理和缓存时间戳。这将有效解决日期以及日的题目。

日期/时间处理

  如果无妥善地、一致地处理好日期及时来说,这将成为一个生累。我们常会逢时区的题材,而且由于日期在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/

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'”。

 

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。

维护服务之安

  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/。

身份验证

  时最为好的做法是用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。

传输安全

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

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

授权

  对劳动之授权和针对性另应用程序的授权一样,没有任何区别。它根据这样一个题材:“主体是否对准加的资源出要的许可?”这里给起了简易的老三件数据(主体,资源同准),因此特别容易构造一个支持这种概念的授权服务。其中中心是受与资源访问许可的人或者体系。使用这些相似概念,就足以呢各一个主题构建一个缓存访问控制列表(ALC)。

授权

  对服务之授权和针对其余应用程序的授权一样,没有外区别。它根据这样一个题材:“主体是不是对准加的资源有要的许可?”这里叫起了简短的老三起数据(主体,资源与许可),因此杀爱构造一个支持这种概念的授权服务。其中核心是给给予资源访问许可的丁或系。使用这些相似概念,就得啊各国一个主题构建一个缓存访问控制列表(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密钥存储在加密底安康密钥库中。

 

应用程序安全

  对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

缓存和可伸缩性

  通过在系统层级消除通过远距离调用来抱请求的数量,缓存提高了系统的可是扩展性。服务通过当应中安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”

 

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)
—— 当服务器抛来特别时,捕捉到的貌似错误。

 

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.

书籍

  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

网站

  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地图