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

相关文章

发表评论

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