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中凡是坐字符串的格式在的,如果不指定统一之格式,那么解析日期呢会见是一个题材。

  betway官网手机版以接口内部,服务端应该坐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

相关文章

admin

网站地图xml地图