JavaRESTful服务至上实践

HTTP状态码(前10)

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

  资源命名的反例

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

资源命名

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

运用Content-Location来拉长响应

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

    弃用

无状态

  正如REST是REpresentational State
Transfer的缩写,无状态很要紧。本质上,那声明了拍卖请求所需的动静已经包涵在伸手我里,也有可能是URI的一片段、查询串参数、body或尾部。URI能够唯一标识每个资源,body中也包括了资源的转态(或转态变更处境)。之后,服务器将拓展处理,将有关的情形或资源通过底部、状态和响应body传递给客户端。

  从事大家这一行业的一大半人都习惯使用容器来编程,容器中有一个“会话”的定义,用于在多个HTTP请求下保持状态。在REST中,如若要在多少个请求下保持用户情状,客户端必须概括客户端的富有音讯来形成请求,要求时再一次发送请求。自从服务端不需求保持、更新或传递会话状态后,无状态性获得了更大的延展。其它,负载均衡器无需担心和无状态系统之间的对话。

  所以状态和资源间有何不一样?服务器对于状态,或者说是应用状态,所关怀的点是在此时此刻对话或请求中要成功请求所需的数目。而资源,或者说是资源气象,则是概念了资源特色的数额,例如存储在数据库中的数据。不问可见,应用状态是是随着客户端和伸手的变动而更改的多寡。相反,资源情形对于发出请求的客户端的话是不变的。

  在网络使用的某一一定岗位上摆放一个回去按钮,是因为它愿意你能按自然的一一来操作吗?其实是因为它违反了无状态的标准化。有过多不坚守无状态原则的案例,例如3-Legged
OAuth,API调用速度限制等。但如故要尽量有限帮助服务器中不须求在七个请求下维持利用状态。

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

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

  根据罗伊Fielding在他的博客中的描述(http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertextdriven),REST接口中最根本的一对是超文本的行使。其它,他还提出,在付给任何有关的新闻以前,一个API应该是可用和可领会的。也就是说,一个API应当可以经过其链接导航到多少的顺序部分。不提议只回去纯数据。

  可是当下的业界先驱们并从未常常采纳那种做法,那浮现了HATEOAS仅仅在成熟度模型中的使用率更高。纵观众多的服务体系,它们基本上重回越来越多的数据,而回到的链接却很少(或者没有)。这是违反Fielding的REST约定的。Fielding说:“音讯的每一个可寻址单元都引导一个地方……查询结果应当突显为一个包含摘要音讯的链接清单,而不是目的数组。”

  另一方面,不难凶狠地将所有链接集合重临会大大影响网络带宽。在实质上意况中,按照所需的规格或行使状态,API接口的通讯量要依据服务器响应中国足球社团一级联赛文本链接所含有的“摘要”数量来抵消。

  同时,充裕利用HATEOAS可能会增加完成的复杂,并对劳动客户端发生明显的承受,这一定于下降了客户端和劳动器端开发人士的生产力。因而,当务之急是要平衡超链接服务实践和水土保持可用资源之间的标题。

  超链接最小化的做法是在最大限度地缩减客户端和服务器之间的耦合的还要,提升服务端的可用性、可操纵性和可明白性。这么些最小化提议是:通过POST创设资源并从GET请求重临集合,对于有分页的意况后边大家会涉及。

安全

  来自维基百科:

局地措施(例如GET、HEAD、OPTIONS和TRACE)被定义为平安的法子,那表示它们仅被用于讯息搜索,而无法改变服务器的情景。换句话说,它们不会有副功效,除了相对来说无害的熏陶如日志、缓存、横幅广告或计数服务等。任意的GET请求,不考虑动用状态的上下文,都被认为是安全的。

  可想而知,安全意味着调用的法子不会挑起副功用。由此,客户端可以频仍使用安全的请求而不用担心对服务端暴发其余副功用。那象克服务端必须服从GET、HEAD、OPTIONS和TRACE操作的平安概念。否则,除了对消费端发生模糊外,它还会导致Web缓存,搜索引擎以及其他活动代理的标题——那将在服务器上发出意想不到的结果。

  根据定义,安全操作是幂等的,因为它们在服务器上暴发相同的结果。

  安全的点子被已毕为只读操作。但是,安全并不表示服务器必须每一次都回来相同的响应。

 

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暴光不安全的操作——它应该永远都无法改改服务器上的此外资源。

可缓存

  在万维网上,客户端能够缓存页面的响应内容。由此响应都应隐式或显式的概念为可缓存的,若不足缓存则要防止客户端在三番四回请求后用旧数据或脏数据来响应。管理得当的缓存会部分地或完全地除了客户端和服务端之间的竞相,进一步校正质量和延展性。

  分页

ETag Header

  ETag
header对于阐明缓存数据的新旧程度很有用,同时也有助于条件的读取和更新操作(分别为GET和PUT)。它的值是一个任意字符串,用来代表回到数据的版本。不过,对于再次来到数据的例外格式,它也得以不一样——JSON格式响应的ETag与同样资源XML格式响应的ETag会差距。ETag
header的值可以像带有格式的底层域对象的哈希表(例如Java中的Obeject.hashcode())一样简单。提议为每个GET(读)操作重临一个ETag
header。其它,确保用双引号包括ETag的值,例如:

  ETag: “686897696a7c876b7e”

 

外加资源

  通过特征来操作资源

  当客户端收到包蕴元数据的资源的特征时,在有权力的情景下,客户端已控制的足足的音信,可以对服务端的资源开展删改。

REST火速提醒

    排序

引言

  安全

正文重要读者

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

  本文中的率领规范一致适用于工程师们,他们愿意采用那么些按照最佳实践标准开发的服务。尽管他们尤为珍惜缓存、代理规则、监听及安全等连锁方面,可是该文档能作为一份包括所有品种服务的总指南。

  别的,通过从那一个率领原则,管理人士了然到开创公共的、提供高稳定的服务所需开销的极力,他们也可从中收益。

 

引言

  现今已有大批量关于RESTful
Web服务至上实践的连带材料(详见本文最终的连锁文献部分)。由于撰文的时刻各异,许多素材中的内容是争论的。别的,想要通过查阅文献来打听那种服务的升华是不太可取的。为了打探RESTful这一定义,至少需求查阅三到五本有关文献,而本文将可以帮你加速这一进程——放弃多余的座谈,最大化地提炼出REST的一流实践和正规。

  与其说REST是一套标准,REST更像是一种标准的汇集。除了两个基本点的尺度外就不曾任何的专业了。实际上,固然有所谓的“最佳实践”和标准,但那么些东西都和宗派斗争一样,在时时刻刻地衍生和变化。

  本文围绕REST的宽广难题指出了看法和仿食谱式的研商,并透过介绍一些不难易行的背景知识对创立真实情况下的预生产环境中一致的REST服务提供文化。本文收集了来自别的渠道的信息,经历过一遍次的破产后不断立异。

  但对此REST格局是或不是必然比SOAP好用仍有较大争议(反之亦然),也许在一些处境下仍亟需成立SOAP服务。本文在提及SOAP时并未花较大篇幅来谈谈它的相持优点。相反由于技术和行业在不断进步,大家将继承细水长流我们的假若–REST是当下统筹web服务的特级艺术。

  第一部分概述REST的含义、设计准则和它的分外之处。第二有些列举了有些小贴士来记念REST的服务意见。之后的一对则会更尖锐地为web服务创制人员提供部分细节的援救和议论,来促成一个力所能及了解展示在生产条件中的高品质REST服务。

 

  无状态

  POST

  自描述的新闻

  每条信息都带有充裕的数目用于确认音信该如何处理。例如要由网络媒体类型(已知的如MIME类型)来确认需调用哪个解析器。响应同样也表明了它们的缓存能力。

  结果限制

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

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

  除了上述内容外,HATEOS也表示,需要的时候链接也可被含有在再次回到的body(或尾部)中,以提供URI来查找对象自我或涉嫌对象。下文将对此举办更详尽的阐发。

  统一接口是各种REST服务统筹时的画龙点睛准则。

  GET

缓存和可伸缩性

  通过在系统层级消除通过远程调用来得到请求的数目,缓存升高了系统的可扩大性。服务通过在响应中安装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

    过滤

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

  许多客户端未来拜会的资源可能在新本子引入后会被扬弃掉,因而,他们必要有一种办法来发现和监察他们的应用程序对弃用资源的行使。当呼吁一个弃用资源时,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”}

 

排序

  排序决定了从服务端再次来到的笔录的一一。也就是对响应中的多条记下举行排序。

  同样,大家那边只考虑部分相比较不难的动静。推荐使用排序字符串查询参数,它富含了一组用分隔符分隔的属性名。具体做法是,默许对每个属性名按升序排列,借使属性名有前缀”-“,则按降序排列。用竖线(”|”)分隔每个属性名,那和后面过滤效果中的参数名/值对的做法无异于。

  举个例证,如若大家想按用户的姓和名进行升序排序,而对雇佣时间开展降序排序,请求将是这么的:

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

  再一次强调一下,查询参数名/值对中的属性名要和服务端再次回到的习性名相匹配。此外,由于排序操作相比较复杂,我们只对须求的资源提供排序成效。即使须要的话也得以在客户端对小的资源汇集举办排列。

 

链接格式

  参照整个链接格式的规范,提议听从一些近乎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

    自描述的音信

回到表征

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

如何时候应该创制一个新本子?

  API开发中的很多地点都会打破约定,并最后对客户端暴发部分不良影响。如若您不确定API的修改会牵动哪些的后果,有限帮助起见最好考虑采用版本控制。当你在设想提供一个新本子是或不是适当时,或者考虑对现有的回来表征进行修改是不是必然能满足急需并被客户端所接受时,有这般多少个要素要考虑。

结果的过滤和排序

  针对重返结果,还须求考虑怎么着在服务端对数码开展过滤和排列,以及怎么着按指定的顺序对子数据举办查找。那一个操作可以与分页、结果限制,以及字符串查询参数filter和sort等相结合,可以兑现强大的数据检索作用。

  再强调一回,过滤和排序都是扑朔迷离的操作,不必要默许提须求持有的资源。下文将介绍如何资源须要提供过滤和排序。

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

询问,过滤和分页

  对于大数据集,从带宽的角度来看,限制重临的数据量是那么些主要的。而从UI处理的角度来看,限制数据量也一如既往任重(英文名:rèn zhòng)而道远,因为UI寻常只可以显示大数量集中的一小部分多少。在数据集的拉长速度不确定的景况下,限制默许再次来到的数据量是很有须求的。以推特(TWTR.US)为例,要收获某个用户的推文(通过个人主页的时日轴),如果没有专门指定,请求默许只会回来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标识的资源数量。

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

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

  可缓存

  带有Content-Type的链接

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

定义

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'”。

 

传输安全

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

  在HTTP和HTTPS之间切换会带来安全隐患,最好的做法是有所简报默许都利用TLS。

分页

  上述格局通过请求方指定数据集的界定来限制重回结果,从而达成分页功效。上面的例证中一共有66条记下,要是每页25条记下,要来得第二页数据,Range
header的始末如下:

  Range: items=25-49

  同样,用字符串查询参数表示如下:

  GET …?offset=25&limit=25

  服务端会相应地回到一组数据,附带的Content-Range header内容如下:

  Content-Range: 25-49/66

  在一大半状态下,那种分页格局都尚未难题。但偶尔会有这种情景,就是要回到的笔录数据不可能直接代表成多少集中的行号。还有就是有些数据集的扭转很快,不断会有新的数量插入到多少集中,那样自然会招致分页出现难点,一些双重的数码或者会冒出在差别的页中。

  按日期排列的数据集(例如推文(Tweet)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/**

  应用HTTP动词表示一些含义

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

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

REST是什么

    小小的化链接推荐

  经过情节协商协理版本管理

  PUT

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

  找出帮衬的本子

    破坏性的修改

结果限制

  “给出第3到第55条的记录”,那种请求数据的法子和HTTP的字节范围规范更平等,因而我们可以用它来标识Range
header。而“从第2条记下初阶,给出最多20条记下”那种艺术更便于阅读和透亮,由此我们寻常会用字符串查询参数的艺术来代表。

  综上所述,推荐既帮助采纳HTTP Range
header,也支撑选取字符串查询参数——offset(偏移量)和limit(限制),然后在服务端对响应结果开展界定。注意,若是还要支持那三种方法,那么字符串查询参数的预先级要超越Range
header。

  那里您恐怕会有个问号:“那三种方法效果相似,不过回去的数目不完全一致。那会不会令人歪曲呢?”恩…那是八个难题。首先要应对的是,那真的会令人歪曲。关键是,字符串查询参数看起来尤其清晰易懂,在营造和剖析时尤其便于。而Range
header则越来越多是由机器来行使(偏向于底层),它越是契合HTTP使用专业。

  可想而知,解析Range
header的工作会增添复杂度,相应的客户端在打造请求时也亟需开展局地甩卖。而采纳单独的limit和offset参数会愈发便于了解和营造,并且不要求对开发人士有更多的渴求。

授权

  对服务的授权和对其他应用程序的授权一样,没有此外差异。它根据这样一个题材:“主体是否对给定的资源有请求的许可?”那里给出了简便的三项数据(主体,资源和认可),因而很简单构造一个支撑那种概念的授权服务。其中大旨是被给予资源访问许可的人或种类。使用那一个相似概念,就可以为每一个大旨营造一个缓存访问控制列表(ALC)。

劳动版本管理

    用范围标记举办界定

过滤

  在本文中,过滤被定义为“通过特定的尺度来规定必必要回去的数额,从而收缩重返的多少”。倘诺服务端帮助一套完整的可比运算符和错综复杂的规格非凡,过滤操作将变得分外复杂。不过大家普通会利用一些简约的表达式,如starts-with(以…开头)或contains(包含)来展开匹配,以确保重回数据的完整性。

  在我们开端商量过滤的字符串查询参数从前,必须先知道怎么要选择单个参数而不是七个字符串查询参数。从根本上来说是为了削减参数名称的争持。大家早就有offsetlimitsort(见下文)参数了。假使可能的话还会有jsonpformat标识符,或许还会有afterbefore参数,那么些都是在本文中涉及过的字符串查询参数。字符串查询中应用的参数更加多,就越可能导致参数名称的争辩,而选取单个过滤参数则会将争论的可能降到最低。

  此外,从服务端也很不难仅经过单个的filter参数来判定请求方是或不是要求多少过滤效果。即便查询须求的复杂度增加,单个参数将更享有灵活性——可以协调建立一套功效完全的查询语法(详见下文OData注释或访问http://www.odata.org)。

  通过引入一组广泛的、公认的分隔符,用于过滤的表明式可以以充足直观的款式被选择。用这一个分隔符来设置过滤查询参数的值,那个分隔符所创造的参数名/值对可以更加便于地被服务端解析并增强多少查询的习性。近期已有些分隔符包含用来分隔每个过滤短语的竖线(”|”)和用来分隔参数名和值的双冒号(”::”)。那套分隔符丰硕唯一,并符合一大半景况,同时用它来创设的字符串查询参数也越来越简单通晓。上面将用一个简短的例子来介绍它的用法。即使我们想要给名为“托德”的用户们发送请求,他们住在巴拿马城,有着“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)。

联合接口

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

日子/时间处理

REST疾速提醒

  (依照地方提到的四个标准化)不管在技术上是或不是RESTful的,那里有部分像样REST概念的提议。遵循它们,可以落成更好、更使得的服务:

卷入响应

   服务器可以在响应中并且重返HTTP状态码和body。有不少JavaScript框架没有把HTTP状态响应码重返给最后的开发者,那往往会招致客户端无法按照情状码来确定具体的作为。别的,就算HTTP规范中有很各种响应码,但是往往唯有少数客户端会关心这个——平日大家只在乎”success”、”error”或”failture”。由此,将响应内容和响应状态码封装在蕴藏响应消息的风味中,是有要求的。

  OmniTI
实验室有诸如此类一个提议,它被喻为JSEND响应。更多新闻请参见http://labs.omniti.com/labs/jsend。此外一个提案是由道格拉斯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>

  按需编码(可选)

  Body内容中的日期/时间种类化

HTTP动词

    本身应当同时支持多少个本子?

  授权

应用程序安全

  对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密钥存储在加密的平安密钥库中。

 

外加资源

  如曾几何时候应该创造一个新本子?

    超媒体即接纳状态引擎(HATEOAS)

网站

  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状态码(前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)
—— 当服务器抛出格外时,捕捉到的一般错误。

 

复数

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

  在你的层级结构中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是实惠的。好吧…

 

小小的化链接推荐

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

  对于从服务端重回的特色集合,每个表征应该在它的链接集合中带走一个小小的的“自身”链接属性。为了便利分页操作,别的的链接可以放在一个独自的链接集合中回到,必要时方可涵盖“第一页”、“上一页”、“下一页”、“最终一页”等消息。

  参照下文链接格式部分的事例获取愈多音讯。

资源命名

  身份验证

根据范围的响应

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

  书籍

  应用程序安全

  DELETE

理所当然的资源名

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

  适当的资源名称为服务端请求提供上下文,伸张服务端API的可驾驭性。通过URI名称分层地查看资源,可以给使用者提供一个谈得来的、简单了然的资源层次,以在他们的应用程序上选用。资源名称应当是名词,防止为动词。使用HTTP方法来指定请求的动作部分,能让事情更是的明通晓白。

弃用

  Deprecated(弃用)的目标是用来注解资源对API依然可用,但在未来会不存在并变得不可用。留意:弃用的时长将由弃用政策决定——那里并从未付诸定义。

  基于资源

  差距资源需要用URI来唯一标识。重临给客户端的特性和资源本身在概念上有所不一样,例如服务端不会一贯传送一个数据库资源,不过,一些HTML、XML或JSON数据可见显得部分数据库记录,如用德语来表明如故用UTF-8编码则要基于请求和服务器达成的底细来决定。

  网站

经过情节协商扶助版本管理

  以往,版本管理通过URI本身的版本号来成功,客户端在呼吁的URI中标明要获取的资源的版本号。事实上,许多大商厦如推特(TWTR.US)、Yammer、非死不可、谷歌等不时在她们的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”}

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

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

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

  Offset参数的值与Range
header中的类似,也是从0开首揣度。Limit参数的值是回去记录的最大数据。当字符串查询参数中未指定limit时,服务端应当提交一个缺省的最大limit值,可是那一个参数的应用都亟需在文档中进行求证。

幂等性

  不要从字面意思来领会什么是幂等性,恰恰相反,那与某些意义紊乱的小圈子毫不相关。上边是缘于维基百科的分解:

在电脑科学中,术语幂等用于更周全地叙述一个操作,两遍或频仍推行该操作暴发的结果是平等的。依据使用的上下文,那或者有例外的意义。例如,在章程仍然子例程调用所有副成效的景况下,意味着在率先调用之后被涂改的情形也保险不变。

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

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

    据悉范围的响应

定义

    非破坏性的改动

  呼吁不协助的版本

缓存和可伸缩性

HTTP动词

  Http动词主要听从“统一接口”规则,并提需要大家相应的基于名词的资源的动作。最重大仍旧最常用的http动词(或者叫做方法,那样称呼可能更恰当些)有POST、GET、PUT和DELETE。那个分别对应于创制、读取、更新和删除(CRUD)操作。也有过多任何的动词,不过利用功能比较低。在这几个使用较少的法子中,OPTIONS和HEAD往往利用得更加多。

  结果的过滤和排序

  XML和JSON

  幂等性

  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。

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作为响应。在它被统统淘汰往日,那是终极一个可被一定的地点。

  ETag Header

破坏性的修改

  • 变动属性名(例如将”name”改成”firstName”)
  • 删去属性
  • 变更属性的数据类型(例如将numeric变为string,
    boolean变为bit/numeric,string 变为 datetime等等)
  • 更改验证规则
  • 在Atom样式的链接中,修改”rel”的值
  • 在现有的工作流中引入须要资源
  • 改变资源的定义/意图;概念/意图或资源情状的含义分化于它原有的含义。例如:
    • 一个content
      type是text/html的资源,之前表示的是负有匡助的媒体类型的一个”links”集合,而新的text/html则代表的是用户输入的“web浏览器表单”。
    • 一个包涵”end提姆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(增删查改)功效,可以使资源的创立变得更便于。随后,你可以成立那一个依据用例和压缩通讯量的资源。

  联合接口

非破坏性的改动

  • 在回到的JSON中添加新属性
  • 添加指向任何资源的”link”
  • 添加content-type援救的新格式
  • 添加content-language支持的新格式
  • 是因为API的创造者和消费者都要拍卖分裂的casing,因而casing的更动毫无干系主要

  资源URI示例

找出援救的本子

  C-S架构

 

版本控制应在怎么级别出现?

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

处理跨域难点

   大家都听说过关于浏览器的同源策略或同源性须要。它指的是浏览器只好请求当前正在展现的站点的资源。例如,如果当前正值突显的站点是www.Example1.com,则该站点不可以对www.Example.com倡议呼吁。鲜明那会潜移默化站点访问服务器的办法。

  近年来有八个被广泛接受的支撑跨域请求的方法:JSONP和跨域资源共享(CORS)。JSONP或“填充的JSON”是一种采纳格局,它提供了一个措施请求来自分歧域中的服务器的数据。其行事方法是从服务器再次来到任意的JavaScript代码,而不是JSON。客户端的响应由JavaScript解析器进行分析,而不是一贯解析JSON数据。别的,CORS是一种web浏览器的技巧标准,它为web服务器定义了一种方法,从而允许服务器的资源可以被差距域的网页访问。CORS被看做是JSONP的新型替代品,并且可以被所有现代浏览器帮衬。因而,不指出接纳JSONP。任何动静下,推荐选用CORS。

支行系统

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

资源命名的反例

  前边大家曾经钻探过一些老少咸宜的资源命名的例证,可是有时一些反面的事例也很有教育意义。上面是一对不太具有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”指的是一个资源吗?因而,这里大家费些口舌也是愿意您能够通晓……

带有Content-Type的链接

  Atom风格的链接辅助”type”属性。提供丰富的音讯以便客户端可以对一定的本子和情节类型进行调用。

    经过特色来操作资源

C-S架构

  统一接口使得客户端和服务端相互分开。关切分离意味什么?打个比方,客户端不须求仓储数据,数据都留在服务端内部,那样使得客户端代码的可移植性获得了提高;而服务端不须求考虑用户接口和用户景况,那样一来服务端将越加简便易行易拓展。只要接口不改变,服务端和客户端可以单独地开展研发和替换。

服务版本管理

   坦率地讲,一说到版本就会令人认为很忙绿,很劳苦,不太简单,甚至会令人觉得痛心——因为那会大增API的复杂度,并还要可能会对客户端爆发部分影响。因而,在API的宏图中要尽量防止多少个例外的版本。

  不帮忙版本,不将版本控制作为不好的API设计的借助。即使您在APIs的布署中引入版本,那迟早都会让你抓狂。由于重临的数目经过JSON来突显,客户端会由于差异的版本而接受到分歧的特性。那样就会设有一些难点,如从内容本身和认证规则方面改变了一个已存在的性质的意思。

  当然,我们无能为力幸免API可能在好哪一天候要求转移再次来到数据的格式和情节,而那也将导致消费端的片段变更,我们相应防止进行局地首要的调整。将API举办版本化管理是幸免那种根本变更的一种有效格局。

身份验证

  方今最好的做法是接纳OAuth身份验证。强烈推荐OAuth2,然而它依旧居于草案景况。或者选用OAuth1,它完全能够胜任。在少数情形下也得以选用3-Legged
OAuth。越来越多关于OAuth的正儿八经可以查阅那里http://oauth.net/documentation/spec/

  OpenID是一个叠加选用。但是指出将OpenID作为一个增大的身份验证选项,以OAuth为主。越来越多关于OpenID的正统能够查阅那里http://openid.net/developers/specs/

日期/时间处理

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

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

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

 

POST

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

  例如:

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

  当创设成功时,重临HTTP状态码201,并顺便一个岗位头音信,其中包含指向起始创制的资源的链接。

  POST请求既不是高枕无忧的又不是幂等的,由此它被定义为非幂等性资源请求。使用四个一样的POST请求很可能会促成成立八个饱含相同音讯的资源。

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

  维护多少个不一样的本子会让劳作变得繁琐、复杂、不难失误,而且代价高,对于任何给定的资源,你应有协助不当先2个版本。

设想连通性

  REST的法则之一就是连通性——通过超媒体链接落成。当在响应中回到链接时,api变的更拥有自描述性,而在没有它们时服务端依然可用。至少,接口本身可以为客户端提供怎么样寻找数据的参阅。其它,在经过POST方法创制资源时,还足以行使头地点包涵一个链接。对于响应中支持分页的会聚,”first”、
“last”、”next”、和”prev”链接至少是老大管用的。

 

    支持CORS

    支持JSONP

  传输安全

用范围标记进行限制

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

  Range: items=0-24

  注意记录是从0开始的接连字段,HTTP规范中验证了怎么利用Range
header来请求字节。也就是说,如若要伏乞数据汇总的第一条记下,范围应该从0起先算起。上述的伏乞将会回来前25个记录,假使数据汇总至少有25条记下。

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

  成立适当粒度的资源

  HTTP
Headers中的日期/时间体系化

回来表征

按需编码(可选)

  服务端通过传输可举办逻辑给客户端,从而为其暂时拓展和定制功用。相关的例子有编译组件Java
applets和客户端脚本JavaScript。

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

  提醒:REST架构中的设计准则中,只有按需编码为可选项。假使某个服务违反了其它随意一项准则,严厉意思上无法称之为RESTful风格。

 

书籍

  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.

  分层系统

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

 

    链接格式

本文主要读者

有限支撑服务的安全

  Authentication(身份验证)指的是认可给定的伸手是从服务已知的某人(或某个系统)发出的,且请求者是他自己所评释的要命人。Authentication是为了印证请求者的实际身份,而authorization(授权)是为着求证请求者有权力去实践被呼吁的操作。

  本质上,这一个进程是那般的:

  1. 客户端发起一个伸手,将authentication的token(身份注解令牌)包蕴在X-Authentication
    header中,或者将token外加在伸手的查询串参数中。
  2. 服务器对authorization
    token(授权令牌)举办检讨,并举办验证(有效且未过期),并依照令牌内容分析或者加载认证焦点。
  3. 服务器调用授权服务,提供验证主题、被呼吁资源和必备的操作许可。
  4. 比方授权通过了,服务器将会继续健康运转。

  下面第三步的支付可能会相比大,不过如果要是存在一个可缓存的权位控制列表(ACL),那么在暴发远程请求前,可以在本土创立一个授权客户端来缓存最新的ACLs。

恳请不帮助的本子

  当呼吁一个不协理的版本号时(包括在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”]

PUT和POST的创设相比较

  同理可得,大家提出利用POST来创制资源。当由客户端来决定新资源具有哪些URI(通过资源名称或ID)时,使用PUT:即借使客户端知道URI(或资源ID)是哪些,则对该URI使用PUT请求。否则,当由服务器或服务端来控制创办的资源的URI时则运用POST请求。换句话说,当客户端在创立以前不精晓(或无法驾驭)结果的URI时,使用POST请求来创立新的资源。

  行使Content-Location来进步响应

REST是什么?

  REST架构格局讲述了七种设计准则。那个用于架构的统筹准则,最早是由罗伊Fielding在他的学士随想中指出并定义了RESTful风格。(详见http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

  七个统筹准则分别是:

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

  以下是这一个安插准则的详细谈论:

  打包响应

Body内容中的日期/时间种类化

  有一个简短的办法可以解决那个标题——在字符串中始终用平等的格式,包蕴时间片(带有时区新闻)。ISO8601时间格式是一个科学的缓解方案,它选用了一心增强的年月格式,蕴含小时、分钟、秒以及秒的小数部分(例如yyyy-MM-dd’T’HH:mm:ss.SSS’Z’)。提出在REST服务的body内容中(请求和响应均包涵)使用ISO8601代表享有的日子格式。

  顺便提一下,对于那么些基于JAVA的服务以来,DateAdapterJ库使用DateAdapter,Iso8601提姆epointAdapter和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/

  客观的资源名

  设想连通性

相关文章