澳门新萄京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

发表评论

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