lovebet爱博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

相关文章