RESTful服务至上实践

    自身什么告知客户端被弃用的资源?

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

  ETag Header

    非破坏性的修改

  C-S架构

REST是什么?

  REST架构形式讲述了六种设计准则。这多少个用于架构的设计准则,最早是由RoyField(Field)ing在他的研究生杂文中提议并定义了RESTful风格。(详见http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

  四个规划准则分别是:

  • 合并接口
  • 无状态
  • 可缓冲
  • C-S架构
  • 分段系统
  • 按需编码

  以下是这一个规划准则的详细座谈:

复数

  让大家来研商一下复数和“单数”的争执…还没听说过?但这种争议确实存在,事实上它可以归纳为这些题材……

  在您的层级结构中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是立竿见影的。好吧…

 

查询,过滤和分页

使用Content-Location来增进响应

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

  分页

  DELETE

HTTP动词

  Http动词重要听从“统一接口”规则,并提供给大家相应的基于名词的资源的动作。最重大依然最常用的http动词(或者叫做方法,这样称呼可能更恰当些)有POST、GET、PUT和DELETE。这多少个分别对应于创建、读取、更新和删除(CRUD)操作。也有许多其他的动词,但是采纳频率相比较低。在这一个应用较少的点子中,OPTIONS和HEAD往往采纳得更多。

  网站

REST是什么

REST神速提醒

  (遵照上边提到的五个尺码)不管在技术上是不是RESTful的,这里有一些看似REST概念的指出。服从它们,能够兑现更好、更使得的劳务:

  按需编码(可选)

资源命名

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

    自描述的音讯

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作为响应。在它被全然淘汰在此以前,这是最终一个可被肯定的地点。

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

  拍卖跨域问题

  Body内容中的日期/时间系列化

可缓存

  在万维网上,客户端可以缓存页面的响应内容。因而响应都应隐式或显式的定义为可缓存的,若不足缓存则要避免客户端在反复请求后用旧数据或脏数据来响应。管理得当的缓存会部分地或完全地除了客户端和服务端之间的相互,进一步改进性能和延展性。

用范围标记举行限制

  当用HTTP header而不是字符串查询参数来取得记录的限定时,Ranger
header应该通过以下内容来指定范围: 

  Range: items=0-24

  注意记录是从0先河的连年字段,HTTP规范中验证了什么样行使Range
header来请求字节。也就是说,假使要乞请数据集中的率先条记下,范围应当从0起头算起。上述的伸手将会重返前25个记录,假诺数据汇总至少有25条记下。

  而在服务端,通过检查请求的Range
header来确定该再次回到哪些记录。只要Range
header存在,就会有一个简短的正则表明式(如”items=(\d+)-(\d+)”)对其展开解析,来得到要寻找的范围值。

分页

  上述模式经过请求方指定数据集的限制来限制重临结果,从而实现分页效率。上边的例证中总共有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=<timestamp&gt

  Range: items=0-19

  GET
http://www.example.com/remarks/home\_timeline?before=<timestamp&gt

*  Range: items=0-19*

  用字符串查询参数表示为:

  GET
http://www.example.com/remarks/home\_timeline?after=<timestamp>&offset=0&limit=20 

*  GET
http://www.example.com/remarks/home\_timeline?before=<timestamp>&offset=0&limit=20*

  有关在不同情状对时间戳的格式化处理,请参见下文的“日期/时间拍卖”。

  如若请求时从没点名要重回的数目范围,服务端重返了一组默认数据或限制的最大数据集,那么服务端同时也理应在重临结果中带有Content-Range
header来和客户端举办确认。以地点个人主页的年月轴为例,无论客户端是不是指定了Range
header,服务端每一遍都只回去20条记下。此时,服务端响应的Content-Range
header应该包含如下内容:

  Content-Range: 0-19/4125

  或 *Content-Range: 0-19/**

    基于资源

授权

  对劳务的授权和对其他应用程序的授权一样,没有其他区别。它依照这样一个题目:“主体是不是对给定的资源有请求的许可?”那里给出了简要的三项数据(主体,资源和批准),由此很容易构造一个支撑这种概念的授权服务。其中重点是被给予资源访问许可的人或系列。使用这一个相似概念,就可以为每一个主旨构建一个缓存访问控制列表(ALC)。

  可缓存

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。

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

 

  基于资源

  不同资源需要用URI来唯一标识。再次来到给客户端的特征和资源本身在概念上有所不同,例如服务端不会平素传送一个数据库资源,不过,一些HTML、XML或JSON数据可知显得部分数据库记录,如用越南语来表述仍旧用UTF-8编码则要遵照请求和服务器实现的底细来决定。

当没有点名版本时,重临什么版本?

  并不需要在每一个伸手中都指定版本号。由于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”}

  书籍

正文首要读者

  传输安全

    支持CORS

带有Content-Type的链接

  Atom风格的链接匡助”type”属性。提供丰硕的音信以便客户端可以对一定的本子和情节类型举办调用。

  采纳Content-Location来增强响应

版本控制应在哪些级别出现?

  提出对单个的资源开展版本控制。对API的有些变动,如修改工作流,也许要跨四个资源的版本控制,以此来预防对客户端暴发破坏性的熏陶。

    过滤

 

  带有Content-Type的链接

  始建适当粒度的资源

  PUT

  结果限制

  版本控制应在咋样级别出现?

引言

结果限制

  “给出第3到第55条的笔录”,这种请求数据的章程和HTTP的字节范围规范更平等,由此我们可以用它来标识Range
header。而“从第2条记下先河,给出最多20条记下”这种方法更便于阅读和精晓,由此大家平常会用字符串查询参数的点子来代表。

  综上所述,推荐既补助接纳HTTP Range
header,也支撑接纳字符串查询参数——offset(偏移量)和limit(限制),然后在服务端对响应结果开展限定。注意,假设还要匡助这二种方法,那么字符串查询参数的事先级要大于Range
header。

  这里您恐怕会有个疑问:“这两种方法效果相似,不过回到的数量不完全一致。这会不会令人歪曲呢?”恩…那是五个问题。首先要应对的是,这着实会让人歪曲。关键是,字符串查询参数看起来更为清晰易懂,在构建和剖析时进一步便民。而Range
header则更多是由机械来采用(偏向于底层),它更加切合HTTP使用标准。

  可想而知,解析Range
header的工作会扩张复杂度,相应的客户端在构建请求时也需要举办部分甩卖。而接纳单独的limit和offset参数会愈来愈容易领会和构建,并且不需要对开发人士有更多的渴求。

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

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

  除了上述情节外,HATEOS也表示,必要的时候链接也可被含有在再次回到的body(或头部)中,以提供URI来探寻对象自我或涉嫌对象。下文将对此举行更详细的阐发。

  统一接口是各样REST服务计划时的必需准则。

劳务版本管理

   坦率地讲,一说到版本就会令人以为很劳顿,很麻烦,不太容易,甚至会令人觉着难受——因为这会大增API的复杂度,并同时可能会对客户端爆发一些震慑。由此,在API的计划中要尽量避免多少个不同的本子。

  不补助版本,不将版本控制作为糟糕的API设计的依赖。假如你在APIs的筹划中引入版本,那迟早都会让您抓狂。由于重返的数额通过JSON来显示,客户端会由于不同的本子而接受到不同的特性。那样就会设有有的题目,如从内容我和阐明规则方面改变了一个已存在的性质的意义。

  当然,大家鞭长莫及避免API可能在某些时候需要改变再次回到数据的格式和内容,而这也将招致消费端的有些变迁,大家相应避免举办部分着重的调动。将API举行版本化管理是避免这种重大变化的一种有效方法。

日期/时间处理

  假如没有妥善地、一致地处理好日期和时间来说,那将改为一个大麻烦。大家平时会际遇时区的题材,而且由于日期在JSON中是以字符串的格式存在的,即便未指定统一的格式,那么解析日期也会是一个题材。

  在接口内部,服务端应该以UTC或GMT时间来囤积、处理和缓存时间戳。这将实惠缓解日期和时间的题材。

护卫服务的资阳

  Authentication(身份注脚)指的是确认给定的伏乞是从服务已知的某人(或某个系统)发出的,且请求者是他协调所表明的可怜人。Authentication是为了证实请求者的实在身份,而authorization(授权)是为着验证请求者有权力去实践被呼吁的操作。

  本质上,这多少个过程是如此的:

  1. 客户端发起一个伸手,将authentication的token(身份评释令牌)包含在X-Authentication
    header中,或者将token叠加在伸手的查询串参数中。
  2. 服务器对authorization
    token(授权令牌)举办反省,并展开认证(有效且未过期),并依照令牌内容分析或者加载认证中央。
  3. 服务器调用授权服务,提供验证中央、被呼吁资源和必要的操作许可。
  4. 如若授权通过了,服务器将会持续健康运作。

  下边第三步的付出可能会相比大,但是即便即便存在一个可缓存的权限决定列表(ACL),那么在发出远程请求前,可以在本地创立一个授权客户端来缓存最新的ACLs。

  无状态

  怎么时候理应创立一个新本子?

    破坏性的改动

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

 

    支持JSONP

  GET

  授权

  创制的资源名

珍惜服务的平安

资源命名的反例

  前边我们曾经研究过部分老少咸宜的资源命名的例子,不过有时一些反面的例证也很有教育意义。下边是部分不太具有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服务以来,开发一个康宁的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密钥存储在加密的平安密钥库中。

 

破坏性的修改

  • 变动属性名(例如将”name”改成”firstName”)
  • 剔除属性
  • 更改属性的数据类型(例如将numeric变为string,
    boolean变为bit/numeric,string 变为 datetime等等)
  • 更改验证规则
  • 在Atom样式的链接中,修改”rel”的值
  • 在存活的工作流中引入必要资源
  • 更改资源的定义/意图;概念/意图或资源意况的意义不同于它原本的意思。例如:
    • 一个content
      type是text/html的资源,在此之前表示的是拥有匡助的传媒类型的一个”links”集合,而新的text/html则意味着的是用户输入的“web浏览器表单”。
    • 一个包含”end提姆(Tim)e”参数的API,对资源”…/users/{id}/exams/{id}”表明的意思是学员在分外时间付诸试卷,而新的意义则是考试的约定完毕时间。
  • 通过充分新的字段来改变现有的资源。将五个资源集合为一个并弃用原来的资源。
    • 有这样五个资源”…/users/{id}/dropboxBaskets/{id}/messages/{id}”和”…/users/{id}/dropboxBaskets/{id}/messages/{id}/readStatus”。新需如果把readStatus资源的属性放到单独的message资源中,并弃用readStatus资源。这将促成messages资源中指向readStatus资源的链接被移除。

  固然下面列出的并不到家,但它交给了部分会对客户端暴发破坏性影响的扭转类型,这时急需考虑提供一个新资源或新本子。

    小小的化链接推荐

创办适当粒度的资源

  一开端,系统中模拟底层应用程序域或数据库架构的API更便于被成立。最后,你会期待将那多少个服务都整合到手拉手——利用多项底层资源缩短通信量。在开立独立的资源之后再创制更大粒度的资源,比从更大的合集中创立较大粒度的资源越来越容易一些。从部分小的容易定义的资源开端,成立CRUD(增删查改)功效,可以使资源的创立变得更便于。随后,你可以成立这么些按照用例和压缩通信量的资源。

  卷入响应

设想连通性

  REST的规律之一就是连通性——通过超媒体链接实现。当在响应中回到链接时,api变的更享有自描述性,而在未曾它们时服务端依然可用。至少,接口本身可以为客户端提供什么寻找数据的参照。其它,在通过POST方法成立资源时,仍可以够接纳头地点包含一个链接。对于响应中协理分页的汇集,”first”、
“last”、”next”、和”prev”链接至少是那一个实惠的。

 

查询,过滤和分页

  对于大数据集,从带宽的角度来看,限制再次回到的数据量是这多少个关键的。而从UI处理的角度来看,限制数据量也一如既往至关首要,因为UI平时只好显示大数目汇总的一小部分数量。在数据集的增长速度不确定的情形下,限制默认重回的数据量是很有必不可少的。以Twitter为例,要拿到某个用户的推文(通过个人主页的刻钟轴),尽管没有特意指定,请求默认只会回去20条记下,尽管系统最多可以回到200条记下。

  除了限制再次来到的数据量,大家还需要考虑什么对天意据集举行“分页”或下拉滚动操作。成立数量的“页码”,重临大数量列表的已知片段,然后标出数据的“前一页”和“后一页”——这一行事被誉为分页。另外,大家可能也急需指定响应元帅包含怎么着字段或性质,从而限制重回值的多寡,并且我们盼望最后可以由此特定值来举办询问操作,并对重返值进行排序。

  有二种重点的办法来还要限制查询结果和推行分页操作。首先,我们得以建立一个目录方案,它可以以页码为导向(请求中要交给每一页的记录数及页码),或者以记录为导向(请求中从来提交第一条记下和最终一条记下)来规定再次来到值的起第一位置。举个例子,这三种办法分别代表:“给出第五页(如若每页有20条记下)的记录”,或“给出第100到第120条的笔录”。

  服务端将基于运作体制来开展切分。有些UI工具,比如Dojo
JSON会采取模仿HTTP规范应用字节范围。假诺服务端匡助out of
box(即开箱即用功用),则前端UI工具和后端服务中间无需任何转换,那样使用起来会很便宜。

  下文将介绍一种艺术,既可以援助Dojo这样的分页情势(在请求头中付出记录的界定),也能补助使用字符串查询参数。这样一来服务端将变得进一步灵敏,既可以动用类似Dojo一样先进的UI工具集,也可以采纳简单直接的链接和标签,而无需再为此扩大复杂的开销工作。但假如服务不间接补助UI效用,可以设想不要在请求头中付出记录范围。

  要专门提出的是,我们并不推荐在享有服务中应用查询、过滤和分页操作。并不是具有资源都默认襄助这一个操作,唯有少数特定的资源才支撑。服务和资源的文档应当表明什么接口补助那一个纷繁的效率。

  幂等性

动用HTTP动词表示一些意思

  任何API的使用者可以发送GET、POST、PUT和DELETE请求,它们很大程度明确了所给请求的目标。同时,GET请求无法更改任何秘密的资源数量。测量和跟踪仍可能暴发,但只会更新数据而不会更新由URI标识的资源数量。

统一接口

  统一接口准则定义了客户端和服务端之间的接口,简化和分手了框架结构,那样一来每个部分都可独自衍变。以下是接口统一的多少个尺码:

身份验证

  近来最好的做法是利用OAuth身份验证。强烈推荐OAuth2,但是它仍旧居于草案意况。或者选拔OAuth1,它完全可以胜任。在一些境况下也可以挑选3-Legged
OAuth。更多关于OAuth的标准可以查看这里http://oauth.net/documentation/spec/

  OpenID是一个叠加采取。但是指出将OpenID作为一个增大的身份验证选项,以OAuth为主。更多关于OpenID的业内可以查阅这里http://openid.net/developers/specs/

创制的资源名

  合理的资源名称或者路径(如/posts/23而不是/api?type=posts&id=23)可以更简明一个呼吁的目的。使用URL查询串来过滤数据是很好的措施,但不应有用于固定资源名称。

  适当的资源名称为服务端请求提供上下文,扩张服务端API的可领会性。通过URI名称分层地翻看资源,可以给使用者提供一个投机的、容易精晓的资源层次,以在她们的应用程序上使用。资源名称应当是名词,避免为动词。使用HTTP方法来指定请求的动作部分,能让事情越来越的一清二楚。

定义

  资源命名的反例

    由此特色来操作资源

  身份验证

REST快速指示

找出协理的版本

PUT和POST的创立相比

  总之,大家提出利用POST来创建资源。当由客户端来决定新资源具有哪些URI(通过资源名称或ID)时,使用PUT:即只要客户端知道URI(或资源ID)是何等,则对该URI使用PUT请求。否则,当由服务器或服务端来控制创办的资源的URI时则使用POST请求。换句话说,当客户端在开创此前不精通(或不可能明白)结果的URI时,使用POST请求来创立新的资源。

  应用程序安全

    我应该而且帮助多少个本子?

外加资源

  结果的过滤和排序

  自描述的消息

  每条音讯都富含丰富的数量用于确认音信该怎么处理。例如要由网络媒体类型(已知的如MIME类型)来认同需调用哪个解析器。响应同样也标志了它们的缓存能力。

自我怎么样告知客户端被弃用的资源?

  许多客户端将来拜会的资源可能在新本子引入后会被吐弃掉,因而,他们需要有一种情势来发现和监察他们的应用程序对弃用资源的施用。当呼吁一个弃用资源时,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生命周期中已经一去不返的资源版本),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”]

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动词

传输安全

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

  在HTTP和HTTPS之间切换会带来安全隐患,最好的做法是装有简报默认都拔取TLS。

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

弃用

  Deprecated(弃用)的目标是用来验证资源对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

缓存和可伸缩性

定义

支持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/

回到表征

  正如前方提到的,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,它概括易读,没有格局和命名空间的限定,换句话来说是无标准的,易于解析。

  请求不匡助的版本

归来表征

外加资源

资源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的例证:

  当没有点名版本时,再次来到什么版本?

C-S架构

  统一接口使得客户端和服务端相互分开。关注分离意味什么?打个假使,客户端不需要仓储数据,数据都留在服务端内部,这样使得客户端代码的可移植性拿到了升级;而服务端不需要考虑用户接口和用户意况,这样一来服务端将越是简便易行易拓展。只要接口不改变,服务端和客户端可以独自地开展研发和替换。

据悉范围的响应

  对一个基于范围的呼吁来说,无论是通过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工具可能不帮忙该符号。

  因此情节协商帮忙版本管理

按需编码(可选)

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

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

  提醒:REST架构中的统筹准则中,唯有按需编码为可选项。假若某个服务违反了此外随意一项准则,严酷意思上不可以称之为RESTful风格。

 

  集合接口

非破坏性的改动

  • 在重回的JSON中添加新属性
  • 累加指向任何资源的”link”
  • 添加content-type协助的新格式
  • 添加content-language匡助的新格式
  • 出于API的奠基人和顾客都要处理不同的casing,由此casing的变化无关重要

结果的过滤和排序

  针对重返结果,还需要考虑怎么在服务端对数码举行过滤和排列,以及咋样按指定的逐条对子数据开展检索。这个操作可以与分页、结果限制,以及字符串查询参数filter和sort等相结合,可以兑现强大的数据检索功效。

  再强调两次,过滤和排序都是扑朔迷离的操作,不需要默认提供给拥有的资源。下文将介绍如何资源需要提供过滤和排序。

我应当同时协助多少个版本?

  维护几个不同的本子会让劳作变得繁琐、复杂、容易失误,而且代价高,对于其余给定的资源,你应该协助不超越2个版本。

  找出协理的本子

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状态码和body。有成千上万JavaScript框架没有把HTTP状态响应码重返给最后的开发者,这频繁会促成客户端不能依据事态码来确定具体的作为。另外,即使HTTP规范中有很多种响应码,不过往往只有个别客户端会关心这个——通常我们只在乎”success”、”error”或”failture”。由此,将响应内容和响应状态码封装在含有响应消息的风味中,是有必要的。

  OmniTI
实验室有这般一个提议,它被誉为JSEND响应。更多消息请参考http://labs.omniti.com/labs/jsend。此外一个提案是由DouglasCrockford指出的,可以查看这里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>

  资源URI示例

幂等性

  不要从字面意思来领会什么是幂等性,恰恰相反,这与某些意义紊乱的领域无关。下边是缘于维基百科的诠释:

在处理器科学中,术语幂等用于更健全地叙述一个操作,一回或频繁推行该操作暴发的结果是同样的。按照使用的上下文,那或者有例外的意义。例如,在措施仍然子例程调用拥有副效用的情状下,意味着在率先调用之后被涂改的意况也保障不变。

  从REST服务端的角度来看,由于操作(或服务端调用)是幂等的,客户端可以用重新的调用而爆发同样的结果——在编程语言中操作像是一个”setter”(设置)方法。换句话说,就是运用五个一样的请求与使用单个请求效果一样。注意,当幂等操作在服务器上发出同样的结果(副功能),响应本身也许是见仁见智的(例如在两个请求之间,资源的情形恐怕会转移)。

  PUT和DELETE方法被定义为是幂等的。查看http请求中delete动词的警戒音信,可以参考下文的DELETE部分。GET、HEAD、OPTIO和TRACE方法自从被定义为平安的章程后,也被定义为幂等的。参照上边关于安全的段子。

无状态

  正如REST是REpresentational State
Transfer的缩写,无状态很关键。本质上,这阐明了拍卖请求所需的事态已经包含在呼吁我里,也有可能是URI的一有的、查询串参数、body或头部。URI可以唯一标识每个资源,body中也包含了资源的转态(或转态变更情形)。之后,服务器将开展处理,将有关的场所或资源通过头部、状态和响应body传递给客户端。

  从事大家这一行当的绝大多数人都习惯使用容器来编程,容器中有一个“会话”的概念,用于在两个HTTP请求下维持状态。在REST中,假如要在多少个请求下维持用户情形,客户端必须概括客户端的具备音讯来完成请求,必要时再次发送请求。自从服务端不需要保障、更新或传递会话状态后,无状态性拿到了更大的延展。另外,负载均衡器无需担心和无状态系统里头的对话。

  所以状态和资源间有哪些差异?服务器对于状态,或者说是应用状态,所关心的点是在此时此刻对话或请求中要成功请求所需的数量。而资源,或者说是资源气象,则是概念了资源特点的数码,例如存储在数据库中的数据。总之,应用状态是是随着客户端和呼吁的更动而更改的多少。相反,资源气象对于发出请求的客户端的话是不变的。

  在网络接纳的某一一定岗位上布置一个回去按钮,是因为它仰望您能按一定的相继来操作吗?其实是因为它违反了无状态的尺度。有许多不服从无状态原则的案例,例如3-Legged
OAuth,API调用速度限制等。但依旧要硬着头皮确保服务器中不需要在五个请求下保持利用状态。

  XML和JSON

网站

  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

    弃用

排序

  排序决定了从服务端重返的记录的各种。也就是对响应中的多条记下举行排序。

  同样,我们这里只考虑部分相比简单的场馆。推荐应用排序字符串查询参数,它蕴含了一组用分隔符分隔的属性名。具体做法是,默认对各类属性名按升序排列,如果属性名有前缀”-“,则按降序排列。用竖线(”|”)分隔每个属性名,这和后边过滤效果中的参数名/值对的做法一样。

  举个例证,假使我们想按用户的姓和名举办升序排序,而对雇佣时间开展降序排序,请求将是如此的:

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

  再度强调一下,查询参数名/值对中的属性名要和服务端再次回到的性能名相匹配。其余,由于排序操作相比复杂,我们只对亟待的资源提供排序功能。假如需要的话也可以在客户端对小的资源汇聚举行排列。

 

劳动版本管理

  行使HTTP动词表示一些含义

    链接格式

正文重要读者

  该最佳实践文档适用于对RESTful
Web服务感兴趣的开发人士,该服务为跨三个劳务的零部件提供了较高的可靠性和一致性。依照本文的指引,可急速、广泛、公开地为内外部客户利用。

  本文中的率领原则一致适用于工程师们,他们期望利用这一个按照最佳实践标准开发的劳务。尽管他们进一步体贴缓存、代理规则、监听及安全等有关方面,但是该文档能作为一份包含所有类型服务的总指南。

  另外,通过从这个指点标准,管理人士精晓到创立公共的、提供高稳定的劳务所需花费的全力,他们也可从中获益。

 

处理跨域问题

   我们都听说过有关浏览器的同源策略或同源性需求。它指的是浏览器只好请求当前正在展现的站点的资源。例如,假若当前正值彰显的站点是www.Example1.com,则该站点不能够对www.Example.com倡议呼吁。分明这会影响站点访问服务器的不二法门。

  近年来有多个被大面积接受的支撑跨域请求的格局:JSONP和跨域资源共享(CORS)。JSONP或“填充的JSON”是一种选拔情势,它提供了一个措施请求来自不同域中的服务器的数据。其工作措施是从服务器重临任意的JavaScript代码,而不是JSON。客户端的响应由JavaScript解析器举办辨析,而不是平昔解析JSON数据。另外,CORS是一种web浏览器的技艺专业,它为web服务器定义了一种方法,从而允许服务器的资源得以被不同域的网页访问。CORS被用作是JSONP的新颖替代品,并且可以被抱有现代浏览器补助。由此,不提议利用JSONP。任何意况下,推荐采取CORS。

  通过特征来操作资源

  当客户端收到包含元数据的资源的性状时,在有权力的情状下,客户端已领悟的十足的音讯,可以对服务端的资源开展删改。

HTTP状态码(前10)

  设想连通性

咋样时候应该创建一个新本子?

  API开发中的很多方面都会打破约定,并最终对客户端爆发一些不良影响。假使你不确定API的改动会带来怎样的后果,保险起见最好考虑动用版本控制。当您在考虑提供一个新本子是否合宜时,或者考虑对现有的回到表征举办修改是否必然能满意急需并被客户端所收受时,有诸如此类多少个元素要考虑。

用字符串查询参数举行限制

  字符串查询参数被用作Range
header的替代采取,它采取offset和limit作为参数名,其中offset代表要查询的第一条记下编号(与上述的用于范围标记的items第一个数字同样),limit代表记录的最大条数。下边的事例再次回到的结果与上述用范围标记的例证一样:

  GET http://api.example.com/resources?offset=0&limit=25

  Offset参数的值与Range
header中的类似,也是从0开端盘算。Limit参数的值是回去记录的最大数据。当字符串查询参数中未指定limit时,服务端应当交付一个缺省的最大limit值,不过这个参数的利用都急需在文档中举行认证。

安全

  来自维基百科:

部分方法(例如GET、HEAD、OPTIONS和TRACE)被定义为平安的点子,这意味它们仅被用于信息搜索,而不可能改变服务器的景观。换句话说,它们不会有副成效,除了绝对来说无害的影响如日志、缓存、横幅广告或计数服务等。任意的GET请求,不考虑使用状态的上下文,都被认为是平安的。

  显而易见,安全意味着调用的艺术不会唤起副效用。由此,客户端可以频繁使用安全的呼吁而不用担心对服务端发生其他副功用。这意味服务端必须听从GET、HEAD、OPTIONS和TRACE操作的哈密概念。否则,除了对消费端爆发模糊外,它还会招致Web缓存,搜索引擎以及另外活动代理的题材——这将在服务器上暴发出人意料的后果。

  按照定义,安全操作是幂等的,因为它们在服务器上产生相同的结果。

  安全的法门被实现为只读操作。不过,安全并不代表服务器必须每一次都回来相同的响应。

 

POST

  POST请求平日被用于创立新的资源,特别是被用来创设从属资源。从属资源即归属于其余资源(如父资源)的资源。换句话说,当创设一个新资源时,POST请求发送给父资源,服务端负责将新资源与父资源拓展关联,并分配一个ID(新资源的URI),等等。

  例如:

  POST http://www.example.com/customers
  POST http://www.example.com/customers/12345/orders

  当创建成功时,重临HTTP状态码201,并顺便一个职务头音信,其中含有指向初步创制的资源的链接。

  POST请求既不是高枕无忧的又不是幂等的,因而它被定义为非幂等性资源请求。使用五个一样的POST请求很可能会造成创建多少个饱含相同音讯的资源。

过滤

  在本文中,过滤被定义为“通过一定的标准来规定必须要回来的数码,从而减弱再次来到的数额”。假使服务端协理一套完整的相比运算符和复杂性的规则十分,过滤操作将变得一定复杂。不过我们常见会使用部分简单的表明式,如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)。

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

  REST指点规范之一(依照联合接口规范)是application的情景通过hypertext(超文本)来传输。这就是我们平常所说的Hypertext
As The Engine of Application State
(即HATEOAS,用超文本来作为应用程序状态机),我们在“REST是什么”一节中也论及过。

  遵照RoyField(Field)ing在他的博客中的描述(http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertextdriven),REST接口中最根本的一部分是超文本的运用。此外,他还指出,在付出任何相关的消息在此之前,一个API应该是可用和可通晓的。也就是说,一个API应当可以经过其链接导航到多少的次第部分。不提出只回去纯数据。

  但是当下的业界先驱们并不曾常常应用这种做法,这体现了HATEOAS仅仅在成熟度模型中的使用率更高。纵观众多的服务类别,它们基本上重回更多的数据,而回到的链接却很少(或者尚未)。这是反其道而行之Field(Field)ing的REST约定的。菲尔德(Field)ing说:“信息的每一个可寻址单元都指导一个地址……查询结果应该展现为一个富含摘要新闻的链接清单,而不是目的数组。”

  另一方面,简单粗暴地将所有链接集合重回会大大影响网络带宽。在骨子里意况中,依照所需的基准或选用状态,API接口的通信量要依据服务器响应中超文本链接所涵盖的“摘要”数量来平衡。

  同时,丰裕利用HATEOAS可能会大增实现的复杂,并对劳动客户端发生分明的承担,这一定于降低了客户端和劳务器端开发人士的生产力。由此,当务之急是要平衡超链接服务推行和水土保持可用资源之间的题目。

  超链接最小化的做法是在最大限度地缩短客户端和服务器之间的耦合的还要,进步服务端的可用性、可操纵性和可精晓性。这么些最小化提议是:通过POST创立资源并从GET请求重临集合,对于有分页的动静前面我们会涉及。

    用范围标记举办限制

    用字符串查询参数举行限定

  复数

经过内容协商协理版本管理

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

链接格式

  参照整个链接格式的专业,提出坚守一些好像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

书籍

  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.

ETag Header

  ETag
header对于声明缓存数据的新旧程度很有用,同时也促进条件的读取和翻新操作(分别为GET和PUT)。它的值是一个任意字符串,用来表示回到数据的本子。但是,对于重回数据的不同格式,它也足以不同——JSON格式响应的ETag与同一资源XML格式响应的ETag会不同。ETag
header的值可以像带有格式的底层域对象的哈希表(例如Java中的Obeject.hashcode())一样简单。建议为每个GET(读)操作重临一个ETag
header。另外,确保用双引号包含ETag的值,例如:

  ETag: “686897696a7c876b7e”

 

    排序

  POST

  PUT和POST的创造相比较

  HTTP
Headers中的日期/时间序列化

分层系统

  客户端日常无法注解自己是直接或者直接与端服务器举办连接。中介服务器可以经过启用负载均衡或提供共享缓存来提升系统的延展性。分层时同样要考虑安全策略。

日期/时间处理

引言

  现今已有雅量关于RESTful
Web服务至上实践的连带材料(详见本文最终的连锁文献部分)。由于撰文的小运不一,许多材料中的内容是争执的。其它,想要通过翻看文献来驾驭这种服务的前进是不太可取的。为了打探RESTful这一定义,至少需要查阅三到五本有关文献,而本文将能够帮你加快这一历程——放任多余的琢磨,最大化地提炼出REST的特级实践和标准。

  与其说REST是一套标准,REST更像是一种口径的集纳。除了多少个基本点的规范外就从未有过其他的正规了。实际上,固然有所谓的“最佳实践”和正规,但那几个事物都和宗教斗争一样,在不停地衍生和变化。

  本文围绕REST的大规模问题指出了看法和仿食谱式的座谈,并透过介绍部分简约的背景知识对创建真实境况下的预生产环境中一样的REST服务提供文化。本文收集了来自另外渠道的音讯,经历过一回次的败诉后不断改进。

  但对于REST形式是否必然比SOAP好用仍有较大争议(反之亦然),也许在好几情状下仍急需创建SOAP服务。本文在提及SOAP时并未花较大篇幅来谈谈它的相对优点。相反由于技术和行业在不断提高,大家将继续坚定不移不懈大家的比方–REST是及时统筹web服务的特等模式。

  第一有的概述REST的意义、设计准则和它的奇特之处。第二局部点数了一些小贴士来回想REST的劳务理念。之后的一些则会更深切地为web服务创制人士提供部分细节的支撑和座谈,来贯彻一个可知驾驭显示在生育环境中的高质地REST服务。

 

Body内容中的日期/时间体系化

  有一个概括的办法可以解决这个题材——在字符串中平素用相同的格式,包括时间片(带有时区音信)。ISO8601时间格式是一个毋庸置疑的解决方案,它使用了截然增强的大运格式,包括刻钟、秒钟、秒以及秒的小数部分(例如yyyy-MM-dd’T’HH:mm:ss.SSS’Z’)。指出在REST服务的body内容中(请求和响应均包括)使用ISO8601代表享有的日子格式。

  顺便提一下,对于这一个基于JAVA的服务以来,Date艾达pterJ库使用DateAdapter,Iso8601提姆(Tim)epoint艾达(Ada)pter和HttpHeader提姆estampAdapter类可以十分容易地分析和格式化ISO8601日期和时间,以及HTTP
1.1
header(RFC1123)格式。可以从https://github.com/tfredrich/DateAdapterJ下载。

  对于那个创设基于浏览器的用户界面来说,ECMAScript5标准一起始就包含了JavaScript解析和创办ISO8601日期的内容,所以它应该成为我们所说的主流浏览器所遵守的措施。当然,倘使您要协助这么些无法自动解析日期的旧版浏览器,可以采纳JavaStript库或正则表明式。那里有几个可以分析和开创ISO8601时间的JavaStript库:

  http://momentjs.com/

  http://www.datejs.com/

    基于范围的响应

  安全

微小化链接推荐

  在create的用例中,新建资源的URI(链接)应该在Location响应头中回到,且响应核心是空的——或者只含有新建资源的ID。

  对于从服务端再次来到的特色集合,每个表征应该在它的链接集合中带走一个不大的“自身”链接属性。为了便利分页操作,其余的链接可以放在一个单身的链接集合中回到,必要时方可涵盖“第一页”、“上一页”、“下一页”、“最后一页”等音讯。

  参照下文链接格式一些的例证获取更多音信。

资源命名

网站地图xml地图