依照财富,基于财富

  C-S架构

弃用

  Deprecated(弃用)的指标是用来证实财富对API依旧可用,但在今后会不设有并变得不可用。专注:弃用的时间长度将由弃用政策决定——那里并没有交到定义。

  XML和JSON

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六遍照旧尚未被调用的法力等同。其它,GET(以及HEAD)是幂等的,那象征使用七个相同的呼吁与运用单个的呼吁最后都存有同样的结果。

  不要通过GET暴露不安全的操作——它应当永远都不能够改改服务器上的任何财富。

财富通过链接的可发现性(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约定的。菲尔德ing说:“音讯的每2个可寻址单元都指引贰个地方……查询结果应该显示为二个包括摘要新闻的链接清单,而不是指标数组。”

  另一方面,简单残忍地将一切链接集合重返会大大影响互联网带宽。在其实际意况况中,根据所需的尺码或应用意况,API接口的通讯量要基于服务器响应Chinese Football Association Super League文本链接所涵盖的“摘要”数量来平衡。

  同时,丰裕利用HATEOAS大概会扩张实现的扑朔迷离,并对服务客户端爆发强烈的承负,这一定于下降了客户端和劳动器端开发职员的生产力。由此,当务之急是要平衡超链接服务实施和现有可用能源之间的难题。

  超链接最小化的做法是在最大限度地减小客户端和服务器之间的耦合的还要,提升服务端的可用性、可操纵性和可通晓性。那个最小化提议是:通过POST创制财富并从GET请求再次来到集合,对于有分页的状态后边我们会涉及。

伸手不协助的版本

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

利用Content-Location来抓牢响应

  可选。见卡宴DF(Resource Description Framework,即能源描述框架)规范。

  开创适当粒度的能源

结果的过滤和排序

  针对重回结果,还亟需考虑什么在服务端对数码举行过滤和排列,以及如何按钦命的逐条对子数据开始展览搜索。这个操作能够与分页、结果限制,以及字符串查询参数filter和sort等相结合,能够完成强大的数据检索效用。

  再强调叁遍,过滤和排序都是扑朔迷离的操作,不须要暗许提需要全数的财富。下文将介绍怎样财富要求提供过滤和排序。

非破坏性的改动

  • 在回来的JSON中添加新属性
  • 拉长指向任何财富的”link”
  • 添加content-type援救的新格式
  • 添加content-language协理的新格式
  • 鉴于API的主要创小编和顾客都要拍卖分化的casing,因而casing的扭转非亲非故紧要

  支行系统

分段系统

  客户端平日无法注明本人是直接只怕间接与端服务器举行连接。中介服务器能够通过启用负载均衡或提供共享缓存来升高系统的延展性。分层时一致要考虑安全策略。

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

  提议对单个的能源举行版本控制。对API的有个别变动,如修改工作流,只怕要跨多少个财富的版本控制,以此来防护对客户端产生破坏性的影响。

自个儿应该而且援助多少个本子?

  维护两个不等的版本会让工作变得繁琐、复杂、不难出错,而且代价高,对于其余给定的能源,你应当辅助不当先一个本子。

  DELETE

链接格式

  参照整个链接格式的专业,建议遵循一些接近Atom、AtomPub或Xlink的作风。JSON-LD也情有可原,但并没有被广泛使用(若是已经被用过)。方今正规最广大的格局是接纳带有”rel”成分和富含能源总体U大切诺基I的”href”元素的Atom链接格式,不包涵其他身份验证或询问字符串参数。”rel”成分得以涵盖标准值”alternate”、”related”、”self”、”enclosure”和”via”,还有分页链接的“第①页”、“上一页”、“下一页”,“最终一页”。在急需时能够自定义并丰裕应用它们。

  一些XML
Atom格式的定义对于用JSON格式表示的链接来说是无效的。例如,METHOD属性对于1个RESTful能源来说是不需求的,因为对此二个加以的财富,在具备帮衬的HTTP方法(CRUD行为)中,财富的U揽胜I都是千篇一律的——所以单独列出那几个是平素不须要的。

  让大家举一些具体的例子来进一步表明这点。下边是调用创设新能源的呼吁后的响应:

  POST http://api.example.com/users

  上面是响应头集合中带有创设新财富的U牧马人I的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请求获取1个包涵分页的性状集合的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对象中所蕴涵的聚众(这几个也是接口要重返给客户端的数目表征集合),在那之中的每一项至少要包涵1个针对性“自个儿(self)”的links集合;另一个则是二个单身的对象links,个中包罗和分页相关的链接,该有的的剧情适用于任何集合。

  对于经过POST请求创造财富的气象,须要在响应头中包涵一个提到新建对象链接的Location

GET

  HTTP的GET方法用于检索(或读取)财富的数额。在正确的呼吁路径下,GET方法会重回一个xml大概json格式的多寡,以及3个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)请求仅用于读取数据而不改变多少。因而,那种应用办法被认为是平安的。也等于说,它们的调用没有数据修改或污染的高风险——调用三次和调用十二次照旧没有被调用的职能等同。别的,GET(以及HEAD)是幂等的,那表示使用五个相同的央求与利用单个的乞求最终都独具同等的结果。

  不要通过GET暴光不安全的操作——它应当永远都不可能修改服务器上的其他财富。

  传输安全

  带有Content-Type的链接

财富命名

  除了适当地使用HTTP动词,在开立三个得以知晓的、易于使用的Web服务API时,能源命名能够说是最富有争议和最重庆大学的概念。二个好的财富命名,它所对应的API看起来更直观并且易于使用。相反,借职分名不佳,同样的API会令人感觉到很愚昧并且难以知晓和接纳。当您供给为你的新API创设能源USportageL时,那里有一对小技巧值得借鉴。

  从实质上讲,二个RESTFul
API最后都得以被回顾地看成是一堆U冠道I的聚集,HTTP调用这么些U索罗德I以及部分用JSON和(或)XML表示的财富,它们中有过多带有了相互关联的链接。RESTful的可寻址能力根本借助ULacrosseI。各种能源都有友好的地方或U奥迪Q5I——服务器能提供的每二个卓有功效的音信都得以当作能源来公开。统一接口的标准部分地由此U大切诺基I和HTTP动词的整合来化解,并符合利用规范和平条约定。

  在控制你系统中要使用的资源时,使用名词来定名这么些财富,而不是用动词或动作来命名。换句话说,一个RESTful
UHavalI应该提到到3个具体的能源,而不是关乎到2个动作。其它,名词还保有部分动词没有的性质,那也是另一个鲜明的因素。

  一些财富的事例:

  • 系统的用户
  • 学员注册的科目
  • 一个用户帖子的日子轴
  • 关怀其余用户的用户
  • 一篇关于骑马的篇章

  服务套件中的每一个能源最少有二个URAV4I来标识。若是那一个U瑞虎I能表示一定的含义并且能够充足描述它所代表的财富,那么它正是1个最好的命名。U帕杰罗I应该拥有可预测性和分层结构,那将推进增强它们的可明白性和可用性的:可预测指的是能源应该和名称保持一致;而分层指的是数额颇具关系上的构造。那并非REST规则或标准,不过它加重了对API的定义。

  RESTful
API是提要求消费端的。U瑞鹰I的称谓和结构应该将它所宣布的意思传达给买主。平常大家很难精晓数据的分界是怎么着,可是从您的数码上您应当很有恐怕去尝试找到要回去给客户端的多少是什么样。API是为客户端而安排的,而不是为您的数据。

  假如大家以后要讲述1个席卷客户、订单,列表项,产品等功效的订单系统。考虑一下我们该怎么来描述在这一个服务中所涉及到的能源的UCR-VIs:

创办适当粒度的财富

  一起头,系统中模拟底层应用程序域或数据库架构的API更便于被创制。最后,你会希望将这一个服务都构成到一块儿——利用多项底层财富减少通讯量。在创建独立的能源之后再次创下立更大粒度的财富,比从更大的合集中创造较大粒度的能源越是便于一些。从部分小的不难定义的能源开头,创造CRUD(增加和删除查改)效能,能够使能源的创始变得更便于。随后,你能够创立这个依照用例和压缩通讯量的财富。

选择Content-Location来增进响应

  可选。见LX570DF(Resource Description Framework,即财富描述框架)规范。

定义

  HTTP
Headers中的日期/时间连串化

REST飞快提醒

  复数

微小化链接推荐

  在create的用例中,新建能源的U揽胜I(链接)应该在Location响应头中回到,且响应中央是空的——可能只含有新建财富的ID。

  对于从服务端重回的表征集合,各种表征应该在它的链接集合中带走2个纤维的“本身”链接属性。为了便于分页操作,其余的链接能够放在贰个独立的链接集合中回到,供给时能够包含“第3页”、“上一页”、“下一页”、“最终一页”等新闻。

  参照下文链接格式局地的例证获取越多消息。

支持JSONP

  JSONP通过运用GET请求避开浏览器的限制,从而完结对全部服务的调用。其工作规律是请求方在伸手的UPAJEROL上添加二个字符串查询参数(例如:jsonp=”jsonp_callback”),个中“jsonp”参数的值是JavaScript函数名,该函数在有响应再次来到时将会被调用。

  由于GET请求中没有包含请求体,JSONP在选择时有着严重的局限性,因而数据必须经过字符串查询参数来传递。同样的,为了援救PUT,POST和DELETE方法,HTTP方法必须也透过字符串查询参数来传递,类似_method=POST这种样式。像那样的HTTP方法传送方式是不引进应用的,这会让服务处于安全风险之中。

  JSONP平时在有个别不辅助COENVISIONS的老旧浏览器中运用,借使要改成协理COPAJEROS的,会潜移默化全体服务器的架构。或许我们也得以透过代办来促成JSONP。总之,JSONP正在被CO大切诺基S所取代,大家应当尽量地使用CO智跑S。

  为了在服务端援救JSONP,在JSONP字符串查询参数字传送递时,响应必需求实践以下那个操作:

  1. 响应体必须封装成3个参数字传送递给jsonp中钦定的JavaScript函数(例如:jsonp_callback(“<JSON
    response body>”))。
  2. 向来重返HTTP状态码200(OK),并且将忠实的情形作为JSON响应中的一部分重临。

  此外,响应体中不时必须包涵响应头。那使得JSONP回调方法需求依照响应体来鲜明响应处理形式,因为它自身不可能得知真实的响应头和情景值。

  上边包车型地铁事例是依照上述办法封装的1个回来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'}")

 

请求不支持的版本

  当呼吁二个不帮衬的本子号时(包括在API生命周期中一度一去不复返的能源版本),API应当重临3个谬误的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”]

DELETE

  DELETE很不难明白。它被用来依据U福睿斯I标识删除财富。

  例如:

  DELETE http://www.example.com/customers/12345
  DELETE http://www.example.com/customers/12345/orders
  DELETE http://www.example.com/buckets/sample

  当删除成功时,再次回到HTTP状态码200(表示正确),同时会顺便2个响应体body,body中大概带有了剔除项的数量(那会占用部分互联网带宽),只怕封装的响应(参见上面包车型地铁重回值)。也能够回去HTTP状态码204(表示无内容)表示从未响应体。总之,能够回到状态码204意味尚未响应体,恐怕重回状态码200而且附带JSON风格的响应体。

  依据HTTP规范,DELETE操作是幂等的。若是您对三个能源实行DELETE操作,财富就被移除了。在能源上翻来覆去调用DELETE最终造成的结果都一模一样:即财富被移除了。但要是将DELETE的操效能于计数器(能源内部),则DETELE将不再是幂等的。如前方所述,只要数据没有被更新,总括和度量的用法依旧可被认为是幂等的。提出非幂等性的财富请求使用POST操作。

  不过,这里有三个有关DELETE幂等性的警告。在多少个财富上第一次调用DELETE往往会回来404(未找到),因为该财富已经被移除了,所以找不到了。那使得DELETE操作不再是幂等的。如果资源是从数据库中删去而不是被总结地方统一标准记为除去,那种情况必要适量让步。

  下表总计出了要害HTTP的措施和财富ULANDI,以及引进的重回值:

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

 

    自描述的信息

定义

非破坏性的修改

  • 在再次来到的JSON中添加新属性
  • 丰硕指向任何财富的”link”
  • 添加content-type帮助的新格式
  • 添加content-language匡助的新格式
  • 由于API的成立者和买主都要处理不相同的casing,因而casing的浮动无关重要

  GET

身份验证

  近期最好的做法是运用OAuth身份验证。强烈推荐OAuth2,然而它照旧处在草案情状。只怕选用OAuth1,它完全能够胜任。在一些意况下也足以采取3-Legged
OAuth。更加多关于OAuth的标准可以查看那里http://oauth.net/documentation/spec/

  OpenID是2个增选举取。可是提出将OpenID作为3个外加的身份验证选项,以OAuth为主。越多关于OpenID的正规能够查看那里http://openid.net/developers/specs/

书籍

  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.

  无状态

劳动版本管理

   坦率地讲,一说到版本就会令人认为很劳碌,很艰巨,不太简单,甚至会令人觉得伤心——因为那会追加API的复杂度,并还要大概会对客户端产生局地影响。因而,在API的设计中要尽量幸免多个差其他本子。

  不帮忙版本,不将版本控制作为不佳的API设计的借助。假诺你在APIs的安顿性中引入版本,那迟早都会让你抓狂。由于再次来到的数量通过JSON来展现,客户端会由于分裂的版本而接受到不相同的性子。这样就会设有部分题材,如从内容本人和表达规则方面改变了一个已存在的性质的含义。

  当然,大家鞭长莫及制止API恐怕在好曾几何时候需求改变重回数据的格式和剧情,而那也将导致消费端的片段变动,我们应有制止举行部分首要的调整。将API进行版本化管理是幸免那种重庆大学变动的一种有效格局。

    破坏性的修改

引言

  于今已有大气关于RESTful
Web服务至上实践的连锁材质(详见本文最后的相关文献部分)。由于撰文的岁月各异,许多素材中的内容是冲突的。别的,想要通过查阅文献来打听那种劳动的前行是不太可取的。为了了然RESTful这一概念,至少须要查阅三到五本有关文献,而本文将能够帮您加速这一历程——吐弃多余的座谈,最大化地提炼出REST的极品实践和标准。

  与其说REST是一套标准,REST更像是一种规格的聚合。除了五个相当重要的规相当就平素不其余的正统了。实际上,尽管有所谓的“最佳实践”和正式,但那些东西都和宗教斗争一样,在频频地演变。

  本文围绕REST的广泛难题提议了意见和仿食谱式的议论,并由此介绍一些大约的背景知识对创立真实意况下的预生产条件中一律的REST服务提供文化。本文收集了来自其他渠道的音信,经历过叁回次的挫败后不断革新。

  但对此REST方式是或不是必然比SOAP好用仍有较大争议(反之亦然),只怕在某个情状下仍须要创立SOAP服务。本文在提及SOAP时并未花较大篇幅来谈谈它的周旋优点。相反由于技术和行业在不断进步,大家将延续坚定不移我们的只要–REST是当时设计web服务的特级方法。

  第②部分概述REST的含义、设计准则和它的特有之处。第2有些列举了有的小贴士来回忆REST的服务意见。之后的有个别则会更尖锐地为web服务成立职员提供部分细节的支持和议论,来达成1个力所能及领悟展现在生养环境中的高品质REST服务。

 

  分页

正文主要读者

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

  本文中的指引原则一致适用于工程师们,他们期望利用这么些依照最佳实践标准开发的服务。固然他们进一步爱惜缓存、代理规则、监听及安全等互为表里地点,不过该文书档案能作为一份包涵全部品类服务的总指南。

  其它,通过从这么些辅导标准,管理人士掌握到开创公共的、提供高稳定的服务所需费用的着力,他们也可从中收益。

 

服务版本管理

   坦率地讲,一说到版本就会令人觉得很费力,很麻烦,不太容易,甚至会令人觉着难熬——因为那会增多API的复杂度,并同时大概会对客户端产生部分震慑。由此,在API的宏图中要尽量防止多个不等的版本。

  不支持版本,不将版本控制作为倒霉的API设计的信赖。假设您在APIs的安排性中引入版本,那迟早都会让您抓狂。由于再次来到的数量经过JSON来突显,客户端会由于差其余版本而接受到差异的性质。那样就会设有有的标题,如从内容本人和认证规则方面改变了八个已存在的属性的意义。

  当然,大家不能制止API大概在好哪一天候必要变更再次来到数据的格式和剧情,而那也将导致消费端的部分变动,大家应当制止进行部分根本的调整。将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”}

 

日子/时间处理

过滤

  在本文中,过滤被定义为“通过一定的原则来规定必供给回到的数据,从而收缩重返的数量”。假若服务端援助一套完整的相比运算符和复杂性的规格相当,过滤操作将变得特出复杂。但是大家平日会采取一些简单易行的表明式,如starts-with(以…初阶)或contains(包涵)来进行匹配,以保险再次来到数据的完整性。

  在大家起始谈论过滤的字符串查询参数从前,必须先清楚怎么要选取单个参数而不是七个字符串查询参数。从根本上来说是为着削减参数名称的争论。大家曾经有offsetlimitsort(见下文)参数了。即使可能的话还会有jsonpformat标识符,或许还会有afterbefore参数,那个都以在本文中提到过的字符串查询参数。字符串查询中应用的参数越来越多,就越或者造成参数名称的抵触,而接纳单个过滤参数则会将争执的只怕降到最低。

  其余,从服务端也很不难仅经过单个的filter参数来判断请求方是还是不是要求多少过滤效果。假诺查询必要的复杂度扩大,单个参数将更具备灵活性——能够友善树立一套效能完全的查询语法(详见下文OData注释或访问http://www.odata.org)。

  通过引入一组广泛的、公认的分隔符,用于过滤的表达式能够以那多少个直观的花样被采用。用这几个分隔符来设置过滤查询参数的值,那个分隔符所创造的参数名/值对能够更为便于地棉被和衣服务端解析并升高多少查询的性质。方今已部分分隔符包蕴用来分隔种种过滤短语的竖线(”|”)和用来分隔参数名和值的双冒号(”::”)。那套分隔符丰盛唯一,并符合大部分状态,同时用它来创设的字符串查询参数也愈加便于通晓。上边将用2个归纳的例证来介绍它的用法。假使大家想要给名为“托德”的用户们发送请求,他们住在西雅图,有着“Grand
Poobah”之称。用字符串查询参数完毕的伸手U景逸SUVI如下:

  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)。

复数

  让我们来探究一下复数和“单数”的争议…还没听旁人讲过?但那种争议确实存在,事实上它能够总结为这些题材……

  在您的层级结构中ULANDI节点是还是不是需求被命名为单数或复数情势吗?举个例证,你用来寻觅用户能源的UOdysseyI的命名是不是供给像下边这样:

  GET http://www.example.com/customer/33245

  或者:

  GET http://www.example.com/customers/33245

  三种情势都没难点,但平常我们都会选取使用复数命名,以使得你的API
UTucsonI在具备的HTTP方法中保持一致。原因是遵照这样一种考虑:customers是劳动套件中的一个凑合,而ID33245的这么些用户则是以此集合中的在那之中叁个。

  根据那几个规则,贰个施用复数方式的多节点的UCRUISERI会是如此(注意粗体部分):

  GET
http://www.example.com/**customers**/33245/**orders**/8769/**lineitems**/1

  “customers”、“orders”以及“lineitems”那些U奥迪Q3I节点都选拔的是复数方式。

  那表示你的各类根能源只必要多个为主的UEscortL就足以了,2个用于创制集合内的财富,另一个用来依据标识符获取、更新和删除财富。例如,以customers为例,创制财富能够动用下边的U牧马人L进行操作:

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

  而读取、更新和删除财富,使用下边包车型大巴ULANDL操作:

  GET|PUT|DELETE http://www.example.com/customers/{id}

  正如前方提到的,给定的财富恐怕有几个UCR-VI,但作为2个微小的完全的增加和删除改查功效,利用多少个简易的USportageI来拍卖就够了。

  大概你会问:是或不是在稍微意况下复数没有意思?嗯,事实上是这么的。当没有集合概念的时候(此时复数没有意思)。换句话说,当能源唯有叁个的境况下,使用单数财富名称也是能够的——即一个纯净的财富。例如,假若有三个十足的完全安插财富,你能够接纳七个单数名称来代表:

  GET|PUT|DELETE http://www.example.com/configuration

  注意那里缺乏configuration的ID以及HTTP动词POST的用法。就算每种用户有3个配备来说,那么这些U奥迪Q5L会是那般:

  GET|PUT|DELETE
http://www.example.com/customers/12345/configuration

  同样令人瞩目那里没有点名configuration的ID,以及从未给定POST动词的用法。在那四个例子中,大概也会有人觉得选拔POST是可行的。好吧…

 

  网站

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

  但是上述提议仅适用于HTTP请求或响应内容中的JSON和XML内容,HTTP规范针对HTTP
headers使用另一种差其余格式。在被奥迪Q7FC1123更替的PRADOFC82第22中学建议,该格式包含了种种日期、时间和date-time格式。可是,提议始终使用时间戳格式,在您的request
headers中它看起来像那样:

  Sun, 06 Nov 1994 08:49:37 GMT

  可是,那种格式没有考虑微秒只怕秒的十进制小数。Java的SimpleDataFormat的格式串是:”EEE,
dd MMM yyyy HH:mm:ss ‘GMT'”。

 

  结果的过滤和排序

网站

  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

  再一次强调一下,查询参数名/值对中的属性名要和服务端重回的天性名相匹配。其余,由于排序操作相比复杂,我们只对亟待的财富提供排序功效。假设须求的话也足以在客户端对小的能源聚合进行排列。

 

  幂等性

  书籍

按需编码(可选)

  服务端通过传输可进行逻辑给客户端,从而为其暂且拓展和定制效率。相关的例证有编写翻译组件Java
applets和客户端脚本JavaScript。

  服从上述条件,与REST架构风格保持一致,能让各种分布式超媒体系统有着梦想的自然属性,比如高品质,延展性,简洁,可变性,可视化,可移植性和可信赖性。

  提醒:REST架构中的布置准则中,唯有按需编码为可选项。假使某些服务违反了其余随意一项准则,严谨意思上不可能称之为RESTful风格。

 

  网站

    基于财富

  自描述的音讯

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

授权

  对劳动的授权和对其他应用程序的授权一样,没有其余区别。它依据这样二个题材:“主体是或不是对给定的资源有请求的许可?”那里给出了不难的三项数据(主体,资源和许可),因而很简单构造多个支撑那种概念的授权服务。个中宗旨是被给予财富访问许可的人或种类。使用那一个相似概念,就能够为每二个主旨营造三个缓存访问控制列表(ALC)。

  创设适当粒度的财富

  运用HTTP动词表示一些意义

分段系统

  客户端常常不能够注解本身是直接或许直接与端服务器进行连接。中介服务器能够由此启用负载均衡或提供共享缓存来提高系统的延展性。分层时一致要考虑安全策略。

  ETag Header

  结果的过滤和排序

卷入响应

   服务器可以在响应中还要再次来到HTTP状态码和body。有过多JavaScript框架没有把HTTP状态响应码重回给最后的开发者,那往往会促成客户端不可能依据景况码来鲜明具体的作为。其它,即便HTTP规范中有很多样响应码,然则往往唯有些客户端会关心这么些——平常大家只在乎”success”、”error”或”failture”。由此,将响应内容和响应状态码封装在含蓄响应消息的风味中,是有必要的。

  OmniTI
实验室有如此一个提出,它被叫做JSEND响应。更加多消息请参考http://labs.omniti.com/labs/jsend。其余3个提案是由DouglasCrockford提议的,能够查阅那里http://www.json.org/JSONRequest.html

  那一个提案在实践中并不曾完全涵盖全部的事态。基本上,今后最好的做法是根据以下属性封装常规(非JSONP)响应:

  • code——包蕴3个平头类型的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仅包蕴错误原因或尤其名称。

  上面是2个回来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>

  结果限制

  POST

资源URI示例

  为了在系统中插入(创建)八个新的用户,大家能够动用:

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

 

  读取编号为33245的用户音讯:

  GET http://www.example.com/customers/33245

  使用PUT和DELETE来请求相同的UPAJEROI,能够立异和删除数据。

 

  下边是对产品有关的U奥德赛I的一些建议:

  POST http://www.example.com/products

  用于成立新的出品。

 

  GET|PUT|DELETE http://www.example.com/products/66432

  分别用于读取、更新、删除编号为66432的产品。

 

  那么,怎么样为用户成立八个新的订单呢?

  一种方案是:

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

  那种措施能够用来创制订单,但紧缺相应的用户数据。

  

  因为大家想为用户创制二个订单(注意之间的关联),那几个UWranglerI恐怕不够直观,下边那些U科雷傲I则更鲜澳优些:

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

  今后大家知晓它是为编号33245的用户制造2个订单。

 

  那上面这几个请求再次回到的是何等吧?

  GET http://www.example.com/customers/33245/orders

  只怕是一个数码为33245的用户所创办或持有的订单列表。注意:大家得以屏蔽对该U酷威I实行DELETE或PUT请求,因为它的操作对象是一个成团。

 

  继续长远,这下边这些U普拉多I的呼吁又象征怎么着吧?

  POST http://www.example.com/customers/33245/orders/8769/lineitems

  大概是(为编号33245的用户)扩张2个编号为8769的订单条目。没错!假若使用GET格局呼吁那几个U兰德GL450I,则会回来这么些订单的保有条条框框。可是,就算这几个条款与用户信息非亲非故,我们将会提供POST
www.example.com/orders/8769/lineitems
这个URI。

  从再次来到的那么些条款来看,钦赐的财富大概会有三个U奥迪Q5Is,所以大家兴许也供给要提供这么三个U奥迪Q3I
GET
http://www.example.com/orders/8769
,用来在不知情用户ID的情况下基于订单ID来查询订单。

 

  更进一步:

  GET http://www.example.com/customers/33245/orders/8769/lineitems/1

  只怕只回去同个订单中的第3个条目。

  今后您应有知道什么是分层结构了。它们并不是严酷的平整,只是为了保障在您的劳务中那些强制的组织能够更易于被用户所知道。与富有软件开发中的技能一样,命名是成功的首要。

  

  多看一些API的以身作则并学会控制这几个技术,和您的队友一起来完善你API能源的U奥迪Q5Is。那里有部分APIs的例证:

  书籍

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

  通过特色来操作财富

  当客户端收到包含元数据的能源的性子时,在有权力的情事下,客户端已控制的够用的信息,能够对服务端的能源拓展删改。

按需编码(可选)

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

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

  提醒:REST架构中的统一筹划准则中,唯有按需编码为可选项。如若有个别服务违反了其余随意一项准则,严刻意思上不能称之为RESTful风格。

 

  身份验证

查询,过滤和分页

找出帮助的版本

  使用Content-Location来加强响应

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)
—— 无论能源存不存在,无论是或不是有40壹 、403的限制,当呼吁的财富找不到时,出于安全因素考虑,服务器都能够使用该错误码来掩饰。

  409 (CONFLICT)
—— 每当执行请求或然会挑起财富争辩时行使。例如,存在重复的实业,当不补助级联删除时去除根对象。

  500 (INTERNAL SERVER ERROR)
—— 当服务器抛出十三分时,捕捉到的一般错误。

 

ETag Header

  ETag
header对于注解缓存数据的新旧程度很有用,同时也推进条件的读取和换代操作(分别为GET和PUT)。它的值是二个任意字符串,用来代表回到数据的本子。可是,对于重临数据的例外格式,它也足以不一样——JSON格式响应的ETag与平等财富XML格式响应的ETag会不相同。ETag
header的值能够录像带有格式的底层域对象的哈希表(例如Java中的Obeject.hashcode())一样简单。提出为各种GET(读)操作重回3个ETag
header。其它,确定保障用双引号包括ETag的值,例如:

  ETag: “686897696a7c876b7e”

 

缓存和可伸缩性

  通过在系统层级消除通过远程调用来赢得请求的数额,缓存进步了系统的可增添性。服务通过在响应中设置headers来增长缓存的力量。遗憾的是,HTTP
1.0中与缓存相关的headers与HTTP
1.1差别,因而服务器要同时扶助二种版本。下表给出了GET请求要补助缓存所不可不的最少headers集合,并付诸了适度的讲述。

HTTP Header

描述

示例

Date

响应再次来到的日子和岁月(KoleosFC1123格式)。

Date: Sun, 06 Nov 1994 08:49:37 GMT

Cache-Control

响应可被缓存的最大秒数(最大age值)。假使响应不补助缓存,值为no-cache。

Cache-Control: 360

Cache-Control: no-cache

Expires

只要给出了最大age值,该时间戳(劲客FC1123格式)表示的是响应过期的小时,也正是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

能源本人最终被修改的年月戳(PRADOFC1123格式)。

Last-Modified: Sun, 06 Nov1994 08:49:37 GMT

  为了简化,那里举二个响应中的headers集合的例证。那是3个简单易行的对财富拓展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

    非破坏性的修改

    自描述的音信

  按需编码(可选)

  资源URI示例

REST是什么?

  REST架构情势讲述了四种设计准则。这么些用于架构的安顿性准则,最早是由罗伊Fielding在他的博士散文中建议并定义了RESTful风格。(详见http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

  多个统一筹划准则分别是:

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

  以下是那几个安顿准则的详尽谈论:

    透过特色来操作能源

  使用HTTP动词表示一些意义

分页

  上述方法通过请求方内定数据集的限制来界定重回结果,从而完成分页效用。上边的例证中总共有66条记下,假设每页25条记下,要显示第三页数据,Range
header的内容如下:

  Range: items=25-49

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

  GET …?offset=25&limit=25

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

  Content-Range: 25-49/66

  在超越44%景色下,那种分页形式都尚未难题。但神跡会有那种景观,正是要回到的笔录数据无法直接表示成多少集中的行号。还有就是有些数据集的转移相当的慢,不断会有新的数额插入到数码集中,那样自然会造成分页出现问题,一些双重的多寡大概晤面世在分化的页中。

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

采纳HTTP动词表示一些意思

  任何API的使用者能够发送GET、POST、PUT和DELETE请求,它们十分大程度分明了所给请求的指标。同时,GET请求不能够改变任何秘密的财富数量。衡量和跟踪仍恐怕发生,但只会更新数据而不会更新由URAV4I标识的能源数量。

定义

授权

  对服务的授权和对其他应用程序的授权一样,没有其他区别。它依据那样三个题材:“主体是或不是对给定的资源有请求的许可?”那里给出了简要的三项数据(主体,能源和批准),因而很简单构造二个帮助那种概念的授权服务。其中大旨是被授予能源访问许可的人或系列。使用这一个相似概念,就能够为每二个大旨构建2个缓存访问控制列表(ALC)。

安全

  来自维基百科:

局地措施(例如GET、HEAD、OPTIONS和TRACE)被定义为安全的法子,那意味它们仅被用来消息搜索,而不能够更改服务器的状态。换句话说,它们不会有副效率,除了相对来说没有毒的熏陶如日志、缓存、横幅广告或计数服务等。任意的GET请求,不考虑接纳状态的上下文,都被认为是平安的。

  总而言之,安全意味着调用的办法不会挑起副功能。因而,客户端能够频仍使用安全的伸手而不用担心对服务端爆发其余副成效。那意味服务端必须遵守GET、HEAD、OPTIONS和TRACE操作的辽源概念。不然,除了对消费端产生模糊外,它还会招致Web缓存,搜索引擎以及别的活动代理的标题——那将在服务器上发出意料之外的结局。

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

  安全的章程被达成为只读操作。可是,安全并不意味服务器必须每趟都回来相同的响应。

 

链接格式

  参照整个链接格式的标准,提议服从一些近似Atom、AtomPub或Xlink的品格。JSON-LD也没错,但并不曾被广大应用(假若已经被用过)。方今正规最广泛的不二法门是选拔含有”rel”成分和带有财富全部UTiguanI的”href”成分的Atom链接格式,不分包其余身份验证或询问字符串参数。”rel”元素得以包括标准值”alternate”、”related”、”self”、”enclosure”和”via”,还有分页链接的“第②页”、“上一页”、“下一页”,“最后一页”。在急需时能够自定义并加上应用它们。

  一些XML
Atom格式的定义对于用JSON格式表示的链接来说是低效的。例如,METHOD属性对于叁个RESTful财富来说是不必要的,因为对此一个加以的财富,在富有帮助的HTTP方法(CRUD行为)中,财富的U奥迪Q7I都是一样的——所以单独列出这个是从未供给的。

  让大家举一些切实的例证来更为验证那或多或少。上面是调用成立新能源的央求后的响应:

  POST http://api.example.com/users

  下边是响应头集合中隐含创立新财富的UPRADOI的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状态码(前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)
—— 无论能源存不设有,无论是不是有40壹 、403的限定,当呼吁的能源找不到时,出于安全因素考虑,服务器都得以采纳该错误码来遮掩。

  409 (CONFLICT)
—— 每当执行请求或然会滋生产资料源争辨时使用。例如,存在重复的实业,当不扶助级联删除时去除根对象。

  500 (INTERNAL SERVER ERROR)
—— 当服务器抛出至极时,捕捉到的形似错误。

 

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——简单、简单阅读,没有情势和命名空间的底细展现——仅仅是多少和链接。如若它比那更复杂的话,参看本节的第3段——使用xml的资本是惊人的。鉴于我们的经验,很少有人利用xml作为响应。在它被统统淘汰以前,那是终极一个可被一定的地点。

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

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

  除了上述情节外,HATEOS也意味,须要的时候链接也可被含有在回到的body(或尾部)中,以提供UPAJEROI来搜寻对象自作者或涉及对象。下文将对此展开更详实的演说。

  统一接口是每一个REST服务安插时的必备准则。

  处理跨域难点

无状态

  正如REST是REpresentational State
Transfer的缩写,无状态很重点。本质上,这证明了处理请求所需的处境已经包罗在呼吁作者里,也有大概是UWranglerI的一有个别、查询串参数、body或尾部。UPRADOI能够唯一标识每一个能源,body中也包蕴了能源的转态(或转态变更情状)。之后,服务器将展开始拍戏卖,将有关的图景或财富通过底部、状态和响应body传递给客户端。

  从事大家这一行业的大部人都习惯使用容器来编制程序,容器中有八个“会话”的定义,用于在七个HTTP请求下维持状态。在REST中,假诺要在多少个请求下保持用户情状,客户端必须总结客户端的富有信息来形成请求,要求时再次发送请求。自从服务端不要求保持、更新或传递会话状态后,无状态性得到了更大的延展。此外,负载均衡器无需担心和无状态系统之间的对话。

  所以状态和财富间有如何分裂?服务器对于状态,恐怕说是应用状态,所关注的点是在现阶段对话或请求中要大功告成请求所需的数量。而能源,只怕说是能源情状,则是概念了财富特点的数码,例如存储在数据库中的数据。综上说述,应用状态是是随着客户端和请求的改动而改变的多寡。相反,能源境况对于发出请求的客户端的话是不变的。

  在互联网采取的某一一定岗位上摆放3个回去按钮,是因为它仰望你能按自然的逐条来操作吗?其实是因为它违反了无状态的条件。有那叁个不遵循无状态原则的案例,例如3-Legged
OAuth,API调用速度限制等。但依旧要硬着头皮有限支撑服务器中不供给在多少个请求下维持利用状态。

    链接格式

用范围标记举行界定

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

  Range: items=0-24

  注意记录是从0起先的连日字段,HTTP规范中证实了哪些运用Range
header来请求字节。也即是说,如若要请求数据汇总的首先条记下,范围应该从0开端算起。上述的乞求将会回到前2四个记录,借使数据汇总至少有25条记下。

  而在服务端,通过检查请求的Range
header来明确该重临哪些记录。只要Range
header存在,就会有贰个简约的正则表达式(如”items=(\d+)-(\d+)”)对其开始展览解析,来获得要物色的范围值。

    弃用

    细微化链接推荐

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

  提议对单个的能源举行版本控制。对API的有的改动,如修改工作流,或许要跨多少个能源的版本控制,以此来严防对客户端产生破坏性的影响。

  授权

回来表征

  正如前方提到的,RESTful接口协理多样能源特色,包罗JSON和XML,以及被包裹的JSON和XML。建议JSON作为暗许表征,但是服务端应该允许客户端钦命别的表征。

  对于客户端请求的性状格式,大家得以在Accept头通过文件扩张名来进展点名,也足以透过query-string等其余方法来钦命。理想图景下,服务端能够援助具有那些主意。但是,未来正规更倾向于经过类似于文件扩大名的办法来进展点名。由此,建议服务端至少必要帮助接纳文件扩张名的点子,例如“.json”,“.xml”以及它们的卷入版本“.wjon”,“.wxml”。

  通过那种艺术,在U酷威I中内定重回表征的格式,可以增进URubiconL的可见性。例如,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头,服务端要同时接济封装和未封装的响应,你必须贯彻自定义的种类——因为那个格式不是正规的连串。这大大扩张了客户端和服务端的扑朔迷离。请参见LacrosseFC
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,它归纳易读,没有方式和命名空间的限制,换句话来说是无标准的,易于解析。

HTTP动词

  Http动词首要遵守“统一接口”规则,并提供给我们相应的依据名词的能源的动作。最要紧照旧最常用的http动词(或然叫做方法,那样称呼恐怕更妥贴些)有POST、GET、PUT和DELETE。那么些分别对应于成立、读取、更新和删除(CRUD)操作。也有成都百货上千其他的动词,不过使用频率相比低。在这个应用较少的格局中,OPTIONS和HEAD往往采取得越多。

排序

  排序决定了从服务端重回的笔录的一一。也正是对响应中的多条记下实行排序。

  同样,大家那里只考虑部分相比容易的景观。推荐应用排序字符串查询参数,它含有了一组用分隔符分隔的属性名。具体做法是,暗中同意对每种属性名按升序排列,倘使属性名有前缀”-“,则按降序排列。用竖线(”|”)分隔每一个属性名,那和近期过滤效果中的参数名/值对的做法无异于。

  举个例证,假设大家想按用户的姓和名进行升序排序,而对雇佣时间实行降序排序,请求将是如此的:

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

  再一次强调一下,查询参数名/值对中的属性名要和服务端再次回到的属性名相匹配。此外,由于排序操作相比复杂,我们只对急需的财富提供排序功效。即使要求的话也足以在客户端对小的能源汇集实行排列。

 

引言

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

弃用

  Deprecated(弃用)的指标是用来证实能源对API依旧可用,但在今日会不存在并变得不可用。瞩目:弃用的时间长度将由弃用政策决定——那里并不曾交到定义。

依照范围的响应

  对二个基于范围的呼吁来说,无论是通过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
content-negotiation(内容协商)遵从类型的“最佳匹配”格局,所以您的API也应该根据这点。根据这一准绳,当客户端从未点名版本时,API应当重返所辅助的最早版本。

  依然这几个事例,获取3个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个含有多版本财富的服务器,来成立二个新用户(预期会回到版本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”}

用字符串查询参数进行界定

  字符串查询参数被看作Range
header的替代选拔,它选取offset和limit作为参数名,个中offset代表要询问的第3条记下编号(与上述的用于范围标记的items第一个数字同样),limit代表记录的最大条数。上面包车型地铁例证重临的结果与上述用范围标记的事例一样:

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

  Offset参数的值与Range
header中的类似,也是从0初步盘算。Limit参数的值是回来记录的最大数目。当字符串查询参数中未钦命limit时,服务端应当交付1个缺省的最大limit值,然而那一个参数的施用都须要在文书档案中举办表明。

  资源URI示例

  应用程序安全

  找出援助的版本

缓存和可伸缩性

  安全

结果限制

  “给出第三到第伍5条的笔录”,那种请求数据的点子和HTTP的字节范围规范更平等,因而我们得以用它来标识Range
header。而“从第壹条记下早先,给出最多20条记下”这种方法更便于阅读和通晓,由此我们普通会用字符串查询参数的法子来代表。

  综上所述,推荐既支持使用HTTP Range
header,也帮忙接纳字符串查询参数——offset(偏移量)和limit(限制),然后在服务端对响应结果开始展览界定。注意,若是还要援救那三种艺术,那么字符串查询参数的优先级要高于Range
header。

  这里您可能会有个问号:“那两种艺术效果相似,不过回到的数量不完全一致。那会不会令人歪曲呢?”恩…那是五个难点。首先要回应的是,那真的会令人歪曲。关键是,字符串查询参数看起来尤其清晰易懂,在构建和剖析时更是有益。而Range
header则更加多是由机器来使用(偏向于底层),它进一步切合HTTP使用标准。

  同理可得,解析Range
header的工作会扩展复杂度,相应的客户端在营造请求时也亟需开始展览局地甩卖。而利用单独的limit和offset参数会愈来愈便于通晓和营造,并且不须要对开发人士有越来越多的渴求。

  统一接口

  财富命名的反例

能源命名的反例

  前边我们已经研讨过局地十二分的财富命名的例证,可是有时一些反面包车型大巴例证也很有教育意义。上面是部分不太具有RESTful风格的能源U宝马X5Is,看起来相比混乱。这几个都以大错特错的例证! 

  首先,一些serivices往往选用单一的UEscortI来内定服务接口,然后经过询问参数来钦点HTTP请求的动作。例如,要翻新编号12345的用户新闻,带有JSON
body的请求恐怕是这么:

  GET
http://api.example.com/services?op=update\_customer&id=12345&format=json

  就算地点UHavalL中的”services”的那一个节点是四个名词,但这几个USportageL不是自解释的,因为对于全数的呼吁而言,该U卡宴I的层级结构都是同一的。其它,它选择GET作为HTTP动词来进行1个更新操作,这差不多正是反人类(甚至是一发千钧的)。

  下边是此外贰个更新用户的操作的例子:

  GET http://api.example.com/update\_customer/12345

  以及它的贰个变种:

  GET http://api.example.com/customers/12345/update

  你会常常看看在其它开发者的服务套件中有很多如此的用法。能够看到,这个开发者试图去创立RESTful的能源名称,而且已经有了部分向上。不过你照旧能够分辨出UTiggoL中的动词短语。注意,在这么些USportageL中大家不须要”update”那些词,因为大家能够依靠HTTP动词来成功操作。上面那一个UPAJEROL正好表达了那或多或少:

  PUT http://api.example.com/customers/12345/update

  这些请求同时设有PUT和”update”,那会对消费者发生迷惑!那里的”update”指的是三个财富吗?由此,那里咱们费些口舌也是梦想你能够知道……

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

  客户端通过body内容、查询串参数、请求头和U库罗德I(财富名称)来传送状态。服务端通过body内容,响应码和响应头传送状态给客户端。那项技能被号称超媒体(或超文本链接)。

  除了上述内容外,HATEOS也象征,要求的时候链接也可被含有在回到的body(或尾部)中,以提供U卡宴I来查找对象自小编或关系对象。下文将对此实行更详尽的阐释。

  统一接口是每一种REST服务统一筹划时的必不可少准则。

    支持CORS

创立适当粒度的财富

  一开端,系统中效仿底层应用程序域或数据库架构的API更便于被创设。最终,你会希望将那些劳动都结合到一同——利用多项底层财富减弱通讯量。在开创独立的能源之后更创设更大粒度的能源,比从更大的合集中创立较大粒度的能源更是不难一些。从一些小的简单定义的财富开首,成立CRUD(增加和删除查改)功效,能够使财富的始建变得更便于。随后,你能够创立那个依据用例和收缩通讯量的财富。

正文主要读者

设想连通性

  REST的法则之一便是连通性——通过超媒体链接达成。当在响应中回到链接时,api变的更兼具自描述性,而在未曾它们时服务端依旧可用。至少,接口本身能够为客户端提供如何寻找数据的参阅。其它,在经过POST方法成立能源时,还能动用头地点包括二个链接。对于响应中援助分页的聚合,”first”、
“last”、”next”、和”prev”链接至少是极度实用的。

 

    支持JSONP

理所当然的财富名

  合理的能源名称或许路径(如/posts/23而不是/api?type=posts&id=23)能够更明了三个请求的指标。使用U中华VL查询串来过滤数据是很好的法门,但不应该用于固定能源名称。

  适当的能源名称为服务端请求提供上下文,扩大服务端API的可通晓性。通过URAV4I名称分层地查看财富,可以给使用者提供叁个要好的、简单明白的财富层次,以在他们的应用程序上选取。财富名称应当是名词,幸免为动词。使用HTTP方法来钦点请求的动作部分,能让工作越来越的明显。

外加财富

REST急迅提醒

  (依照地点提到的多少个标准)不管在技术上是或不是RESTful的,那里有部分接近REST概念的提出。服从它们,能够达成更好、更实用的劳务:

  POST

  基于财富

  差异能源必要用URubiconI来唯一标识。重返给客户端的风味和能源本人在概念上有所区别,例如服务端不会一向传送三个数据库能源,但是,一些HTML、XML或JSON数据可见显得部分数据库记录,如用瑞典语来发挥仍旧用UTF-8编码则要基于请求和服务器完结的底细来支配。

通过剧情协商帮衬版本管理

  现在,版本管理通过UEvoqueI本人的本子号来成功,客户端在呼吁的UTucsonI中标明要获得的财富的版本号。事实上,许多大商厦如推特(TWTR.US)、Yammer、推特(Twitter)、谷歌等不时在他们的U奥迪Q7I里使用版本号。甚至像WSO2那样的API管理工科具也会在它的ULX570Ls中供给版本号。

  面向REST原则,版本管理技术快捷发展。因为它不分包HTTP规范中放到的header,也不补助仅当1个新的财富或概念被引入时才应该添加新U途睿欧I的观点——即版本不是表现格局的转移。另一位演唱会对台戏的说辞是能源U福睿斯I是不会随时间改变的,财富正是财富。

  URubiconI应该能简单地辨认财富——而不是它的“形状”(状态)。另一个正是必须钦定响应的格式(表征)。还有局地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被用来表示所希望的响应格式(以及示例中的版本号),注意上述五个一样的U牧马人I是如何成功在不相同的本子中分辨财富的。只怕,如若客户端需求三个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”}

    支持JSONP

HTTP状态码(前10)

  授权

日子/时间处理

  假使没有妥当地、一致地拍卖好日期和时间的话,这将成为1个大麻烦。大家日常会遇到时区的难题,而且由于日期在JSON中是以字符串的格式存在的,假使未钦点统一的格式,那么解析日期也会是贰个难题。

  在接口内部,服务端应该以UTC或GMT时间来存款和储蓄、处理和缓存时间戳。那将使得消除日期和时间的题材。

传输安全

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

  在HTTP和HTTPS之间切换会带来安全隐患,最好的做法是持有简报暗中认可都使用TLS。

  应用程序安全

接纳HTTP动词表示一些意思

  任何API的使用者能够发送GET、POST、PUT和DELETE请求,它们相当大程度鲜明了所给请求的指标。同时,GET请求不可能更改任何秘密的财富数量。衡量和跟踪仍大概产生,但只会更新数据而不会更新由ULX570I标识的能源数量。

    基于范围的响应

    小小的化链接推荐

幂等性

  不要从字面意思来明白什么是幂等性,恰恰相反,那与有个别职能紊乱的园地无关。上边是缘于维基百科的解释:

在总结机科学中,术语幂等用于更完善地叙述3个操作,三次或频仍实施该操作产生的结果是均等的。依据使用的上下文,那或者有两样的含义。例如,在措施如故子例程调用装有副成效的事态下,意味着在第①调用之后被涂改的处境也保持不变。

  从REST服务端的角度来看,由于操作(或服务端调用)是幂等的,客户端可以用重新的调用而暴发相同的结果——在编程语言中操作像是1个”setter”(设置)方法。换句话说,正是运用多个一样的伸手与使用单个请求效果等同。注意,当幂等操作在服务器上产生同样的结果(副效率),响应自个儿大概是例外的(例如在三个请求之间,能源的情况或许会变动)。

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

  PUT

再次回到表征

HTTP状态码(前10)

叠加财富

    破坏性的改动

支持JSONP

  JSONP通过使用GET请求避开浏览器的限定,从而完结对负有服务的调用。其工作规律是请求方在呼吁的U昂CoraL上添加三个字符串查询参数(例如:jsonp=”jsonp_callback”),在那之中“jsonp”参数的值是JavaScript函数名,该函数在有响应重临时将会被调用。

  由于GET请求中并未包括请求体,JSONP在动用时有着严重的局限性,由此数据必须透过字符串查询参数来传递。同样的,为了支持PUT,POST和DELETE方法,HTTP方法必须也透过字符串查询参数来传递,类似_method=POST那种样式。像这么的HTTP方法传送格局是不引进应用的,那会让服务处于安全危害之中。

  JSONP日常在局地不帮助CO卡宴S的老旧浏览器中动用,即便要改成帮助COXC60S的,会潜移默化总体服务器的架构。或许大家也能够通过代办来落到实处JSONP。总而言之,JSONP正在被CO奥德赛S所代表,我们应该尽量地利用CO陆风X8S。

  为了在服务端支持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'}")

 

正文重要读者

    链接格式

POST

  POST请求平日被用来创制新的财富,特别是被用来创立从属财富。从属财富即归属于其它财富(如父财富)的能源。换句话说,当创设3个新财富时,POST请求发送给父财富,服务端负责将新资源与父能源实行关联,并分配1个ID(新能源的U奥迪Q3I),等等。

  例如:

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

  当创立成功时,重回HTTP状态码201,并顺便2个任务头音信,其中包涵指向起始创造的能源的链接。

  POST请求既不是安全的又不是幂等的,由此它被定义为非幂等质量源请求。使用三个一律的POST请求很或许会导致创立八个带有相同消息的财富。

合并接口

  统一接口准则定义了客户端和服务端之间的接口,简化和分手了架构,那样一来每一种部分都可独自演化。以下是接口统一的三个标准:

支持CORS

  在服务端实现COCR-VS很简短,只须要在出殡和埋葬响应时顺手HTTP头,例如: 

Access-Control-Allow-Origin: *

  唯有在数量是集体使用的气象下才会将拜访来源设置为”*”。当先四分之一情况下,Access-Control-Allow-Origin头应该内定哪些域可以发起四个CO福睿斯S请求。唯有必要跨域访问的USportageL才设置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服务器上陈设三个用空格分隔的域的列表。越多关于COEvoqueS的剧情能够参照那里:http://enable-cors.org/

支持CORS

  在服务端实现COLANDS很不难,只需求在出殡和埋葬响应时顺手HTTP头,例如: 

Access-Control-Allow-Origin: *

  只有在数量是公家使用的场所下才会将造访来源设置为”*”。半数以上气象下,Access-Control-Allow-Origin头应该内定哪些域能够发起贰个CO路虎极光S请求。唯有要求跨域访问的UOdysseyL才设置COOdysseyS头。

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服务器、代理来进展布署,只怕从服务器本身发送。不引进在服务端实现,因为很不利索。或然,能够利用方面包车型大巴第3种方式,在web服务器上布置三个用空格分隔的域的列表。更加多关于COGL450S的始末可以参考那里:http://enable-cors.org/

外加能源

  如何时候应该创设2个新本子?

可缓存

  在万维网上,客户端能够缓存页面包车型大巴响应内容。由此响应都应隐式或显式的定义为可缓存的,若不足缓存则要防止客户端在数十次请求后用旧数据或脏数据来响应。管理妥当的缓存会部分地或完全地除了客户端和服务端之间的互动,进一步革新品质和延展性。

POST

  POST请求平时被用来创造新的能源,特别是被用来创设从属财富。从属能源即归属于其它财富(如父财富)的资源。换句话说,当创制2个新财富时,POST请求发送给父能源,服务端负责将新财富与父能源拓展关联,并分配二个ID(新财富的ULX570I),等等。

  例如:

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

  当创造成功时,再次来到HTTP状态码201,并顺便二个岗位头音信,当中带有指向起先创立的财富的链接。

  POST请求既不是高枕无忧的又不是幂等的,由此它被定义为非幂等品质源请求。使用五个一样的POST请求很恐怕会促成创立三个饱含相同音信的能源。

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

    遵照财富

ETag Header

  ETag
header对于注解缓存数据的新旧程度很有用,同时也促进条件的读取和翻新操作(分别为GET和PUT)。它的值是三个任意字符串,用来表示回到数据的本子。可是,对于重回数据的差异格式,它也得以差异——JSON格式响应的ETag与同一财富XML格式响应的ETag会分歧。ETag
header的值能够录像带有格式的底层域对象的哈希表(例如Java中的Obeject.hashcode())一样简单。建议为各样GET(读)操作再次来到二个ETag
header。其余,确定保障用双引号包涵ETag的值,例如:

  ETag: “686897696a7c876b7e”

 

结果限制

  “给出第③到第45条的记录”,那种请求数据的主意和HTTP的字节范围规范更平等,由此大家得以用它来标识Range
header。而“从第①条记下起先,给出最多20条记下”那种形式更便于阅读和掌握,因而大家一般会用字符串查询参数的办法来代表。

  综上所述,推荐既扶助选择HTTP Range
header,也支撑选择字符串查询参数——offset(偏移量)和limit(限制),然后在服务端对响应结果开始展览限定。注意,假使同时接济那二种办法,那么字符串查询参数的优先级要高于Range
header。

  那里你只怕会有个问号:“那两种办法效果相似,不过回去的数码不完全一致。那会不会令人歪曲呢?”恩…那是七个难题。首先要应对的是,这真的会令人歪曲。关键是,字符串查询参数看起来特别清晰易懂,在创设和剖析时更是便于。而Range
header则越多是由机器来使用(偏向于底层),它进一步符合HTTP使用正规。

  显而易见,解析Range
header的工作会增添复杂度,相应的客户端在创设请求时也急需展开一些拍卖。而选用单独的limit和offset参数会越加不难精通和创设,并且不需求对开发职员有越来越多的须要。

    支持CORS

有限支撑服务的百色

  Authentication(身份验证)指的是承认给定的伸手是从服务已知的某人(或某些系统)发出的,且请求者是她协调所注解的那个家伙。Authentication是为了证实请求者的忠实身份,而authorization(授权)是为着印证请求者有权力去实践被呼吁的操作。

  本质上,这几个进度是那般的:

  1. 客户端发起3个呼吁,将authentication的token(身份认证令牌)包蕴在X-Authentication
    header中,或者将token叠加在呼吁的查询串参数中。
  2. 服务器对authorization
    token(授权令牌)进行检查,并展开求证(有效且未过期),并依照令牌内容分析大概加载认证主题。
  3. 服务器调用授权服务,提供验证核心、被呼吁财富和必备的操作许可。
  4. 设若授权通过了,服务器将会继续健康运作。

  上面第2步的开发或许会相比大,不过如若如若存在1个可缓存的权杖控制列表(ACL),那么在产生远程请求前,能够在该地创造三个授权客户端来缓存最新的ACLs。

网站

  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

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

幂等性

  不要从字面意思来驾驭什么是幂等性,恰恰相反,那与一些意义紊乱的圈子非亲非故。上面是缘于维基百科的表达:

在电脑科学中,术语幂等用于更健全地讲述几个操作,三遍或频仍实践该操作产生的结果是相同的。依据使用的上下文,那可能有两样的含义。例如,在艺术或许子例程调用装有副效率的意况下,意味着在率先调用之后被改动的景况也维持不变。

  从REST服务端的角度来看,由于操作(或服务端调用)是幂等的,客户端可以用重新的调用而发出相同的结果——在编制程序语言中操作像是八个”setter”(设置)方法。换句话说,正是使用三个一律的呼吁与运用单个请求效果同样。注意,当幂等操作在服务器上产生同样的结果(副成效),响应本人可能是例外的(例如在多个请求之间,能源的境况或者会变动)。

  PUT和DELETE方法被定义为是幂等的。查看http请求中delete动词的警戒音讯,能够参见下文的DELETE部分。GET、HEAD、OPTIO和TRACE方法自从被定义为安全的章程后,也被定义为幂等的。参照上面关于安全的段落。

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

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

  有一个粗略的法子可以缓解那些难点——在字符串中始终用平等的格式,包蕴时间片(带有时区新闻)。ISO8601时间格式是3个科学的缓解方案,它采纳了一心增强的年华格式,包蕴时辰、分钟、秒以及秒的小数部分(例如yyyy-MM-dd’T’HH:mm:ss.SSS’Z’)。建议在REST服务的body内容中(请求和响应均包蕴)使用ISO8601代表享有的日子格式。

  顺便提一下,对于那么些基于JAVA的劳务以来,DateAdapterJ库使用DateAdapter,Iso8601TimepointAdapter和HttpHeaderTimestampAdapter类能够十分不难地剖析和格式化ISO8602二日期和时间,以及HTTP
1.1
header(PRADOFC1123)格式。能够从https://github.com/tfredrich/DateAdapterJ下载。

  对于那1个创制基于浏览器的用户界面来说,ECMAScript5正规一开端就带有了JavaScript解析和创造ISO860七日期的内容,所以它应当成为我们所说的主流浏览器所遵从的办法。当然,倘若你要帮忙那多少个不能够自动解析日期的旧版浏览器,可以应用JavaStript库或正则表明式。那里有几个能够分析和创办ISO8601时间的JavaStript库:

  http://momentjs.com/

  http://www.datejs.com/

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

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

  并不须求在每多个请求中都钦命版本号。由于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格式请求2个包罗多版本能源的服务器,来创制多少个新用户(预期会回去版本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”}

  装进响应

    用范围标记举办界定

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

  维护五个不一样的本子会让工作变得繁琐、复杂、不难出错,而且代价高,对于其余给定的财富,你应该帮忙不当先2个本子。

查询,过滤和分页

  对于大数据集,从带宽的角度来看,限制再次来到的数据量是不行重庆大学的。而从UI处理的角度来看,限制数据量也同等至关心珍视要,因为UI平日只可以呈现大数目汇总的一小部分数额。在数据集的增速不鲜明的情况下,限制暗中认可重返的数据量是很有必不可少的。以Twitter为例,要取得某些用户的推文(通过个人主页的时光轴),借使没有专门钦定,请求暗中认可只会回去20条记下,固然系统最多能够回到200条记下。

  除了限制再次回到的数据量,大家还索要考虑什么对命局据集实行“分页”或下拉滚动操作。成立数量的“页码”,再次回到大数量列表的已知片段,然后标出数据的“前一页”和“后一页”——这一行事被叫做分页。其余,大家大概也亟需钦定响应少将包涵怎么样字段或性质,从而限制再次回到值的数码,并且我们愿意最后能够透过特定值来开始展览询问操作,并对重回值举行排序。

  有二种重庆大学的主意来还要限定查询结果和推行分页操作。首先,大家得以创设三个索引方案,它能够以页码为导向(请求中要提交每一页的记录数及页码),或许以记录为导向(请求中央直机关接付出第叁条记下和最后一条记下)来规定重返值的起第四人置。举个例子,那二种办法分别代表:“给出第六页(假如每页有20条记下)的笔录”,或“给出第90到第二20条的笔录”。

  服务端将基于运作体制来实行切分。有个别UI工具,比如Dojo
JSON会选用模仿HTTP规范应用字节范围。要是服务端帮助out of
box(即开箱即用效应),则前端UI工具和后端服务时期无需任何转换,这样使用起来会很有益。

  下文将介绍一种方式,既能够协助Dojo那样的分页格局(在请求头中提交记录的界定),也能支撑采纳字符串查询参数。那样一来服务端将变得尤其灵活,既能够采取类似Dojo一样先进的UI工具集,也足以运用简便直接的链接和标签,而无需再为此扩充复杂的开销工作。但一旦服务不直接援助UI成效,能够考虑不要在请求头中提交记录范围。

  要特别建议的是,大家并不引进在装有服务中使用查询、过滤和分页操作。并不是全体财富都暗许帮助那些操作,唯有少数特定的资源才支撑。服务和财富的文书档案应当表达什么接口支持这几个复杂的职能。

服务版本管理

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

应用程序安全

  对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”的值
  • 在存活的工作流中引入须要能源
  • 转移财富的概念/意图;概念/意图或能源景况的意义分裂于它原本的意思。例如:
    • 2个content
      type是text/html的能源,在此以前表示的是怀有支持的媒体类型的贰个”links”集合,而新的text/html则表示的是用户输入的“web浏览器表单”。
    • 三个包涵”end提姆e”参数的API,对财富”…/users/{id}/exams/{id}”表达的含义是学生在万分时刻付诸试卷,而新的意义则是试验的预订完成时间。
  • 通过添加新的字段来改变现有的能源。将四个财富集合为1个并弃用原来的能源。
    • 有这么三个能源”…/users/{id}/dropboxBaskets/{id}/messages/{id}”和”…/users/{id}/dropboxBaskets/{id}/messages/{id}/readStatus”。新需假设把readStatus财富的性能放到单独的message财富中,并弃用readStatus财富。那将导致messages财富中指向readStatus财富的链接被移除。

  即便上边列出的并不周密,但它交给了一部分会对客户端产生破坏性影响的转移类型,那时需求考虑提供三个新财富或新本子。

拍卖跨域难点

   我们都闻讯过关于浏览器的同源策略或同源性须求。它指的是浏览器只可以请求当前正值呈现的站点的财富。例如,要是当前正值展现的站点是www.Example1.com,则该站点无法对www.Example.com提倡呼吁。显著那会影响站点访问服务器的格局。

  最近有多少个被大面积接受的支撑跨域请求的艺术:JSONP和跨域财富共享(COTiguanS)。JSONP或“填充的JSON”是一种采用方式,它提供了1个主意请求来自分歧域中的服务器的数据。其行事措施是从服务器重回任意的JavaScript代码,而不是JSON。客户端的响应由JavaScript解析器进行解析,而不是一贯解析JSON数据。此外,COLANDS是一种web浏览器的技能专业,它为web服务器定义了一种艺术,从而允许服务器的财富能够被分化域的网页访问。CO福特ExplorerS被视作是JSONP的新式替代品,并且可以被有着现代浏览器扶助。因而,不建议利用JSONP。任何情状下,推荐选取COCR-VS。

    作者怎么着告知客户端被弃用的财富?

  复数

  利用Content-Location来增强响应

  传输安全

保障服务的安全

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

小小化链接推荐

  在create的用例中,新建能源的UHighlanderI(链接)应该在Location响应头中回到,且响应大旨是空的——恐怕只含有新建财富的ID。

  对于从服务端再次来到的特征集合,各类表征应该在它的链接集合中辅导三个小小的的“自己”链接属性。为了有利于分页操作,别的的链接能够置身一个单身的链接集合中回到,供给时得以涵盖“第贰页”、“上一页”、“下一页”、“最终一页”等新闻。

  参照下文链接格式一些的例子获取越来越多消息。

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

    非破坏性的修改

合理的财富名

  合理的财富名称或然路径(如/posts/23而不是/api?type=posts&id=23)能够更简爱他美(Aptamil)个请求的目标。使用U昂科拉L查询串来过滤数据是很好的措施,但不应有用于固定财富名称。

  适当的财富名称为服务端请求提供上下文,扩大服务端API的可掌握性。通过URubiconI名称分层地翻看财富,能够给使用者提供一个自身的、简单精晓的能源层次,以在她们的应用程序上利用。财富名称应当是名词,防止为动词。使用HTTP方法来钦赐请求的动作部分,能让工作越来越的明通晓白。

  分段系统

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

财富通过链接的可发现性(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接口的通讯量要遵照服务器响应Chinese Football Association Super League文本链接所涵盖的“摘要”数量来平衡。

  同时,丰硕利用HATEOAS大概会扩张实现的复杂,并对劳动客户端产生明显的承担,这一定于下跌了客户端和劳务器端开发职员的生产力。因而,当务之急是要平衡超链接服务推行和现有可用能源之间的标题。

  超链接最小化的做法是在最大限度地减小客户端和服务器之间的耦合的还要,进步服务端的可用性、可操纵性和可了然性。那么些最小化建议是:通过POST创制财富并从GET请求重返集合,对于有分页的图景后面我们会涉及。

  处理跨域难题

  C-S架构

  身份验证

集合接口

  统一接口准则定义了客户端和服务端之间的接口,简化和分手了架构,那样一来各样部分都可单独演变。以下是接口统一的四个标准化:

HTTP动词

HTTP动词

  Http动词重要遵从“统一接口”规则,并提须要大家相应的依据名词的能源的动作。最要紧依旧最常用的http动词(或许叫做方法,那样称呼恐怕更稳当些)有POST、GET、PUT和DELETE。这一个分别对应于创制、读取、更新和删除(CRUD)操作。也有成都百货上千别样的动词,不过利用成效比较低。在这个应用较少的措施中,OPTIONS和HEAD往往使用得越来越多。

本身如何告知客户端被弃用的能源?

  许多客户端今后作客的能源只怕在新本子引入后会被吐弃掉,因而,他们需求有一种方法来发现和监督他们的应用程序对弃用财富的选取。当呼吁三个弃用能源时,API应该健康响应,并带有3个布尔类型的自定义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”}

 

PUT

  PUT日常被用于更新能源。通过PUT请求三个已知的能源U大切诺基I时,需求在央浼的body中包蕴对原本能源的更新数据。

  可是,在能源ID是由客服端而非服务端提供的景况下,PUT同样能够被用来创立能源。换句话说,如若PUT请求的U卡宴I中隐含的能源ID值在服务器上不存在,则用于创建财富。同时伸手的body中务必含有要创建的能源的数据。有人认为那会时有产生歧义,所以只有真的需求,使用那种方法来创制财富应该被慎用。

  可能大家也得以在body中提供由客户端定义的财富ID然后使用POST来创立新的能源——假如请求的U奥德赛I中不带有要开创的财富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。

  GET

  结果限制

    弃用

  找出援助的版本

书籍

  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.

  带有Content-Type的链接

缓存和可伸缩性

能源命名的反例

  前面大家早已切磋过局地老少咸宜的能源命名的例证,然则有时一些反面包车型地铁例子也很有教育意义。下边是部分不太具有RESTful风格的财富UTucsonIs,看起来相比较混乱。那一个都以一无所能的事例! 

  首先,一些serivices往往利用单一的U奥迪Q5I来钦定服务接口,然后通过查询参数来钦命HTTP请求的动作。例如,要立异编号12345的用户音讯,带有JSON
body的央求或许是这么:

  GET
http://api.example.com/services?op=update\_customer&id=12345&format=json

  固然地点U奥迪Q3L中的”services”的那么些节点是1个名词,但以此U昂科威L不是自解释的,因为对于具有的伸手而言,该U奥迪Q5I的层级结构都是千篇一律的。其余,它应用GET作为HTTP动词来推行1个创新操作,那简直就是反人类(甚至是危如累卵的)。

  上边是其它1个翻新用户的操作的例子:

  GET http://api.example.com/update\_customer/12345

  以及它的一个变种:

  GET http://api.example.com/customers/12345/update

  你会时不时看看在任何开发者的劳动套件中有好多那样的用法。能够看看,那么些开发者试图去创设RESTful的财富名称,而且已经有了有的上扬。不过你还能够够辨识出U奇骏L中的动词短语。注意,在这一个U奥迪Q5L中大家不须求”update”那么些词,因为我们能够借助HTTP动词来实现操作。上面这些U景逸SUVL正好表明了那或多或少:

  PUT http://api.example.com/customers/12345/update

  这些请求同时设有PUT和”update”,那会对顾客产生迷惑!那里的”update”指的是2个能源吗?因而,那里大家费些口舌也是希望你能够精晓……

  PUT

  伸手不帮助的本子

  通过特色来操作财富

  当客户端收到包涵元数据的能源的特征时,在有权力的情状下,客户端已精通的够用的新闻,能够对服务端的能源拓展删改。

  卷入响应

    透过特征来操作财富

  按需编码(可选)

REST是什么

身份验证

  方今最好的做法是行使OAuth身份验证。强烈推荐OAuth2,可是它依然居于草案景况。大概选拔OAuth1,它完全能够胜任。在某个意况下也能够挑选3-Legged
OAuth。更加多关于OAuth的规范可以查阅那里http://oauth.net/documentation/spec/

  OpenID是多少个外加选用。然而建议将OpenID作为三个附加的身份验证选项,以OAuth为主。越多关于OpenID的行业内部可以查阅那里http://openid.net/developers/specs/

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

日子/时间处理

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

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

  PUT和POST的成立相比较

    自作者应该同时援救多少个本子?

定义

能源命名

设想连通性

  REST的法则之一正是连通性——通过超媒体链接达成。当在响应中回到链接时,api变的更具有自描述性,而在未曾它们时服务端依然可用。至少,接口本身能够为客户端提供什么样寻找数据的参考。别的,在通过POST方法创设能源时,还足以行使头地点包括一个链接。对于响应中帮忙分页的集结,”first”、
“last”、”next”、和”prev”链接至少是这一个管用的。

 

由此剧情协商协理版本管理

  现在,版本管理通过U大切诺基I本人的本子号来成功,客户端在呼吁的U帕杰罗I中标明要拿走的财富的版本号。事实上,许多大专营商如Facebook、Yammer、Facebook、谷歌(Google)等不时在她们的USportageI里使用版本号。甚至像WSO2那样的API管理工科具也会在它的U景逸SUVLs中供给版本号。

  面向REST原则,版本管理技术快速发展。因为它不包涵HTTP规范中放置的header,也不援助仅当叁个新的财富或概念被引入时才应该添加新UHavalI的见地——即版本不是表现方式的扭转。另一个反对的说辞是能源U汉兰达I是不会随时间改变的,能源就是财富。

  U奥迪Q5I应该能大致地辨识能源——而不是它的“形状”(状态)。另三个就是必须钦定响应的格式(表征)。还有局地HTTP
headers:Accept 和 Content-Type。Accept
header允许客户端钦命所希望或能支撑的响应的传播媒介类型(一种或各种)。Content-Type
header可分别被客户端和服务端用来钦定请求或响应的数额格式。

  例如,要博得1个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被用来代表所企望的响应格式(以及示例中的版本号),注意上述四个相同的UENCOREI是何等做到在不一致的本子中分辨财富的。大概,尽管客户端须要一个XML格式的多少,可以将Accept
header设置为”application/xml”,假设供给的话也得以带3个点名的版本号。

  由于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在发送数据给服务器时的用处,那里给出3个用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”}

正文重要读者

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

  本文中的引导标准一致适用于工程师们,他们愿意利用这一个依据最佳实践标准开发的劳务。纵然她们更是敬重缓存、代理规则、监听及安全等息息相关地点,但是该文书档案能作为一份包括全体项目服务的总指南。

  此外,通过从那一个带领规范,管理职员领会到创造公共的、提供高稳定的劳重力管理服务所需费用的努力,他们也可从中收益。

 

PUT和POST的创制相比较

  不问可见,大家提出采纳POST来创建能源。当由客户端来支配新财富有着何等U兰德HighlanderI(通过财富名称或ID)时,使用PUT:即假诺客户端知道U劲客I(或财富ID)是如何,则对该UTucsonI使用PUT请求。不然,当由服务器或服务端来决定创办的财富的UTiguanI时则选取POST请求。换句话说,当客户端在创制在此以前不知道(或无法明白)结果的U中华VI时,使用POST请求来创立新的资源。

  基于能源

  不相同能源须要用U索罗德I来唯一标识。重回给客户端的特征和财富自身在概念上有所不一致,例如服务端不会直接传送二个数据库能源,然则,一些HTML、XML或JSON数据可见显得部分数据库记录,如用土耳其语来表述依旧用UTF-8编码则要基于请求和服务器达成的底细来支配。

资源URI示例

  为了在系统中插入(创制)一个新的用户,大家能够动用:

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

 

  读取编号为33245的用户消息:

  GET http://www.example.com/customers/33245

  使用PUT和DELETE来请求相同的ULacrosseI,能够创新和删除数据。

 

  下边是对产品有关的UEvoqueI的一些提出:

  POST http://www.example.com/products

  用于创制新的出品。

 

  GET|PUT|DELETE http://www.example.com/products/66432

  分别用于读取、更新、删除编号为66432的产品。

 

  那么,怎样为用户创制二个新的订单呢?

  一种方案是:

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

  那种方法得以用来创制订单,但贫乏相应的用户数量。

  

  因为大家想为用户创制3个订单(注意之间的涉嫌),这几个UEscortI恐怕不够直观,上边那几个U昂CoraI则更鲜圣元些:

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

  以后大家知晓它是为编号33245的用户创立一个订单。

 

  那上面这么些请求再次回到的是怎样吗?

  GET http://www.example.com/customers/33245/orders

  恐怕是三个号码为33245的用户所创建或持有的订单列表。注意:大家能够遮挡对该URI实行DELETE或PUT请求,因为它的操作对象是三个集合。

 

  继续深切,那上面那些U昂科威I的呼吁又代表怎样吧?

  POST http://www.example.com/customers/33245/orders/8769/lineitems

  恐怕是(为编号33245的用户)扩张二个号码为8769的订单条目。没错!假设选拔GET格局呼吁这么些UTiguanI,则会再次回到那么些订单的富有条条框框。不过,如若这几个条款与用户消息无关,大家将会提供POST
www.example.com/orders/8769/lineitems
这个URI。

  从重回的这一个条款来看,钦命的能源只怕会有多少个U冠道Is,所以大家恐怕也供给要提供那样三个ULacrosseI
GET
http://www.example.com/orders/8769
,用来在不清楚用户ID的境况下基于订单ID来查询订单。

 

  更进一步:

  GET http://www.example.com/customers/33245/orders/8769/lineitems/1

  可能只回去同个订单中的第3个条款。

  未来你应该清楚什么是分层构造了。它们并不是严刻的条条框框,只是为着确定保证在您的劳动中这个强制的布局能够更易于被用户所知晓。与持有软件开发中的技能一样,命名是打响的第贰。

  

  多看有个别API的以身作则并学会控制这几个技能,和你的队友一起来宏观你API财富的U昂科雷Is。那里有一部分APIs的事例:

  能源命名的反例

 

护卫服务的平安

日子/时间拍卖

找出援救的本子

C-S架构

  统一接口使得客户端和服务端相互分开。关切分离意味什么?打个比方,客户端不须要仓储数据,数据都留在服务端内部,这样使得客户端代码的可移植性获得了晋级;而服务端不要求考虑用户接口和用户处境,那样一来服务端将进而简便易行易拓展。只要接口不改动,服务端和客户端能够独自地展开研发和替换。

分页

  上述格局通过请求方钦点数据集的限量来限制重临结果,从而达成分页功用。上边的例子中一起有66条记下,假若每页25条记下,要出示第①页数据,Range
header的内容如下:

  Range: items=25-49

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

  GET …?offset=25&limit=25

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

  Content-Range: 25-49/66

  在超过3/6意况下,那种分页情势都并未难点。但神跡会有这种状态,便是要重回的笔录数据不可能直接表示成多少集中的行号。还有就是有个别数据集的变迁非常的慢,不断会有新的多寡插入到数码集中,那样自然会造成分页出现难题,一些双重的数量大概会出现在分歧的页中。

  按日期排列的数据集(例如Facebookfeed)就是一种普遍的动静。就算你还是能对数据开始展览分页,但有时候用”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/**

HTTP Headers中的日期/时间类别化

  但是上述建议仅适用于HTTP请求或响应内容中的JSON和XML内容,HTTP规范针对HTTP
headers使用另一种差异的格式。在被帕杰罗FC1123更替的RubiconFC82第22中学指出,该格式包蕴了各个日期、时间和date-time格式。然则,提出始终使用时间戳格式,在你的request
headers中它看起来像那样:

  Sun, 06 Nov 1994 08:49:37 GMT

  然而,那种格式没有考虑微秒或然秒的十进制小数。Java的SimpleDataFormat的格式串是:”EEE,
dd MMM yyyy HH:mm:ss ‘GMT'”。

 

什么样时候应该创立3个新本子?

  API开发中的很多方面都会打破约定,并最终对客户端产生局地不良影响。假若您不显著API的改动会带来什么样的结果,保证起见最好考虑使用版本控制。当您在考虑提供二个新本子是还是不是适宜时,大概考虑对现有的回到表征进行改动是还是不是肯定能满意急需并被客户端所收受时,有这么多少个要素要考虑。

劳务版本管理

    排序

处理跨域问题

   大家都听外人讲过有关浏览器的同源策略或同源性必要。它指的是浏览器只好请求当前正在呈现的站点的能源。例如,假使当前正值展现的站点是www.Example1.com,则该站点无法对www.Example.com提倡呼吁。分明那会影响站点访问服务器的情势。

  最近有五个被大规模接受的支撑跨域请求的措施:JSONP和跨域能源共享(COLANDS)。JSONP或“填充的JSON”是一种采纳格局,它提供了3个办法请求来自区别域中的服务器的数据。其工作形式是从服务器重返任意的JavaScript代码,而不是JSON。客户端的响应由JavaScript解析器实行剖析,而不是直接解析JSON数据。此外,CO帕杰罗S是一种web浏览器的技艺专业,它为web服务器定义了一种方法,从而允许服务器的财富得以被分裂域的网页访问。COCRUISERS被用作是JSONP的新式替代品,并且可以被全部现代浏览器协助。因而,不提出选用JSONP。任何景况下,推荐接纳CO汉兰达S。

REST快捷提醒

  (依据上边提到的五个规范)不管在技术上是或不是RESTful的,那里有局地类似REST概念的建议。服从它们,能够兑现更好、更实惠的劳动:

    过滤

C-S架构

  统一接口使得客户端和服务端相互分开。关怀分离意味什么?打个假使,客户端不必要仓库储存数据,数据都留在服务端内部,那样使得客户端代码的可移植性获得了提拔;而服务端不须要考虑用户接口和用户情况,那样一来服务端将尤其简明易拓展。只要接口不转移,服务端和客户端能够独自地拓展研究开发和替换。

  因而剧情协商援助版本管理

包裹响应

   服务器能够在响应中而且再次回到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仅包蕴错误原因或尤其名称。

  下边是2个回到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>

重回表征

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

  合理的财富名

安全

  来自维基百科:

部分方法(例如GET、HEAD、OPTIONS和TRACE)被定义为平安的措施,那表示它们仅被用于新闻寻找,而无法改变服务器的情事。换句话说,它们不会有副功能,除了相对来说无毒的熏陶如日志、缓存、横幅广告或计数服务等。任意的GET请求,不考虑使用状态的上下文,都被认为是平安的。

  由此可见,安全意味着调用的艺术不会滋生副效率。由此,客户端能够屡屡使用安全的请求而不用担心对服务端产生其余副效用。这表示服务端必须遵循GET、HEAD、OPTIONS和TRACE操作的资阳概念。不然,除了对消费端产生模糊外,它还会导致Web缓存,搜索引擎以及其它活动代理的标题——这将在服务器上发出意料之外的结局。

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

  安全的办法被完结为只读操作。不过,安全并不意味服务器必须每回都回来相同的响应。

 

  可缓存

能源命名

  除了适当地使用HTTP动词,在成立1个能够清楚的、易于使用的Web服务API时,能源命名能够说是最具有争议和最要害的概念。一个好的能源命名,它所对应的API看起来更直观并且易于使用。相反,借义务名倒霉,同样的API会令人觉得很古板并且难以知晓和选取。当您供给为你的新API创制能源U科雷傲L时,那里有一部分小技巧值得借鉴。

  从本质上讲,2个RESTFul
API最后都能够被不难地作为是一堆U智跑I的成团,HTTP调用那一个U奥德赛I以及一些用JSON和(或)XML表示的财富,它们中有很多包罗了相互关联的链接。RESTful的可寻址能力根本依赖UPAJEROI。每种财富都有谈得来的地方或UPRADOI——服务器能提供的每二个实用的新闻都能够当作财富来公开。统一接口的口径部分地经过U福特ExplorerI和HTTP动词的咬合来缓解,并符合利用正式和平条约定。

  在决定你系统中要利用的财富时,使用名词来命名那一个财富,而不是用动词或动作来定名。换句话说,1个RESTful
UTucsonI应该提到到二个有血有肉的财富,而不是涉嫌到2个动作。其余,名词还存有局地动词没有的属性,那也是另七个醒指标要素。

  一些能源的例子:

  • 系统的用户
  • 学员注册的教程
  • 3个用户帖子的时光轴
  • 爱戴入微其余用户的用户
  • 一篇关于骑马的小说

  服务套件中的每一种能源最少有贰个URubiconI来标识。假设这些U智跑I能表示肯定的意思并且能够尽量描述它所表示的能源,那么它正是两个最好的命名。U奥德赛I应该具有可预测性和支行结构,那将促进增强它们的可了解性和可用性的:可预测指的是能源应该和名称保持一致;而分层指的是数额有所关系上的构造。那并非REST规则或标准,可是它加重了对API的定义。

  RESTful
API是提需要消费端的。U昂科雷I的称号和结构应当将它所公布的意思传达给买主。常常我们很难知晓数据的分界是什么样,不过从你的数码上你应该很有恐怕去品味找到要重返给客户端的数额是如何。API是为客户端而设计的,而不是为您的多寡。

  若是咱们未来要讲述一个包罗客户、订单,列表项,产品等职能的订单系统。考虑一下大家该怎么来讲述在那个服务中所涉及到的财富的UEvoqueIs:

复数

  让大家来研究一下复数和“单数”的抵触…还没听他们说过?但这种争议确实存在,事实上它能够归咎为这些标题……

  在你的层级结构中UENCOREI节点是还是不是须求被取名为单数或复数格局呢?举个例子,你用来寻觅用户财富的U昂科威I的命名是还是不是必要像上面那样:

  GET http://www.example.com/customer/33245

  或者:

  GET http://www.example.com/customers/33245

  三种方法都没难题,但常常我们都会选择选择复数命名,以使得你的API
U牧马人I在享有的HTTP方法中保持一致。原因是依据那样一种考虑:customers是服务套件中的三个聚集,而ID33245的那一个用户则是这么些集合中的个中3个。

  依据那一个规则,一个利用复数方式的多节点的URubiconI会是如此(注意粗体部分):

  GET
http://www.example.com/**customers**/33245/**orders**/8769/**lineitems**/1

  “customers”、“orders”以及“lineitems”这几个U本田CR-VI节点都使用的是复数格局。

  那意味你的各样根财富只必要七个为主的UPAJEROL就能够了,二个用于创制集合内的能源,另三个用来依照标识符获取、更新和删除能源。例如,以customers为例,创制财富得以选拔上边包车型客车U奥迪Q3L举行操作:

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

  而读取、更新和删除财富,使用上面包车型地铁UTucsonL操作:

  GET|PUT|DELETE http://www.example.com/customers/{id}

  正如前方提到的,给定的能源或者有多个U途锐I,但作为一个小小的一体化的增加和删除改查功效,利用两个简易的USportageI来处理就够了。

  恐怕你会问:是或不是在稍微景况下复数没有意义?嗯,事实上是这么的。当没有集合概念的时候(此时复数没有意义)。换句话说,当财富唯有一个的情事下,使用单数能源名称也是可以的——即3个单一的财富。例如,借使有3个纯粹的欧洲经济共同体布局能源,你可以动用1个单数名称来代表:

  GET|PUT|DELETE http://www.example.com/configuration

  注意那里贫乏configuration的ID以及HTTP动词POST的用法。假诺每一种用户有一个陈设来说,那么这些UTiggoL会是这么:

  GET|PUT|DELETE
http://www.example.com/customers/12345/configuration

  同样令人瞩目那里没有点名configuration的ID,以及没有给定POST动词的用法。在那多个例证中,或许也会有人认为采取POST是立竿见影的。好吧…

 

PUT和POST的开创相比

  不问可见,大家提出使用POST来成立财富。当由客户端来决定新财富具有哪些UTucsonI(通过财富名称或ID)时,使用PUT:即只要客户端知道USportageI(或能源ID)是怎么,则对该U智跑I使用PUT请求。不然,当由服务器或服务端来控制成立的财富的URAV4I时则选用POST请求。换句话说,当客户端在创造之前不知情(或不能知道)结果的U福特ExplorerI时,使用POST请求来创设新的能源。

  设想连通性

基于范围的响应

  对一个依据范围的乞请来说,无论是通过HTTP的Range
header照旧经过字符串查询参数,服务端都应有有2个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工具或许不帮助该符号。

查询,过滤和分页

    自个儿应当而且帮忙多少个版本?

REST快速提醒

PUT

  PUT常常被用于革新能源。通过PUT请求1个已知的能源UENVISIONI时,需求在呼吁的body中包罗对原本能源的翻新数据。

  然则,在财富ID是由客服端而非服务端提供的情事下,PUT同样能够被用来创设能源。换句话说,借使PUT请求的U福睿斯I中带有的能源ID值在服务器上不设有,则用于创立财富。同时伸手的body中务必包含要开创的能源的数量。有人以为那会时有产生歧义,所以唯有真的须要,使用那种方法来创立财富应该被慎用。

  恐怕大家也足以在body中提供由客户端定义的财富ID然后使用POST来成立新的财富——假若请求的U景逸SUVI中不带有要成立的财富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。

怎么样时候理应创制1个新本子?

  API开发中的很多地点都会打破约定,并最后对客户端发生部分不良影响。借使您不明确API的修改会推动哪些的后果,保险起见最好考虑选拔版本控制。当您在设想提供1个新本子是或不是安妥时,恐怕考虑对现有的回来表征进行改动是或不是必然能满意急需并被客户端所承受时,有诸如此类多少个因素要考虑。

带有Content-Type的链接

  Atom风格的链接扶助”type”属性。提供丰裕的音讯以便客户端能够对一定的本子和内容类型举行调用。

  合并接口

传输安全

  全体的表明都应当使用SSL。OAuth2供给授权服务器和access
token(访问令牌)来利用TLS(安全传输层协议)。

  在HTTP和HTTPS之间切换会带来安全隐患,最好的做法是怀有简报暗中认可都施用TLS。

  XML和JSON

  理所当然的能源名

  自描述的音讯

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

过滤

  在本文中,过滤被定义为“通过特定的规则来规定须求求回到的多寡,从而收缩重返的多寡”。倘使服务端帮助一套完整的比较运算符和复杂性的原则杰出,过滤操作将变得非凡复杂。可是我们一般会动用一些简易的表明式,如starts-with(以…初叶)或contains(包括)来拓展匹配,以管教再次来到数据的完整性。

  在大家发轫探讨过滤的字符串查询参数在此以前,必须先明了为什么要动用单个参数而不是多少个字符串查询参数。从根本上来说是为了减小参数名称的争执。大家早已有offsetlimitsort(见下文)参数了。如若恐怕的话还会有jsonpformat标识符,大概还会有afterbefore参数,这几个都以在本文中涉及过的字符串查询参数。字符串查询中央银行使的参数更加多,就越大概造成参数名称的争执,而选用单个过滤参数则会将龃龉的可能降到最低。

  其它,从服务端也很容易仅经过单个的filter参数来判定请求方是还是不是须要多少过滤效果。假诺查询须求的复杂度扩充,单个参数将更兼具灵活性——能够协调建立一套功用一体化的询问语法(详见下文OData注释或访问http://www.odata.org)。

  通过引入一组广泛的、公认的分隔符,用于过滤的表明式能够以老大直观的款式被运用。用那一个分隔符来设置过滤查询参数的值,这个分隔符所创制的参数名/值对能够越发不难地棉被和衣服务端解析并抓牢数据查询的习性。方今已有的分隔符包蕴用来分隔各样过滤短语的竖线(”|”)和用来分隔参数名和值的双冒号(”::”)。那套分隔符充分唯一,并符合超越百分之五十地方,同时用它来营造的字符串查询参数也愈加容易明白。上边将用二个大概的例子来介绍它的用法。如果大家想要给名为“托德”的用户们发送请求,他们住在天津,有着“Grand
Poobah”之称。用字符串查询参数落成的请求U宝马X3I如下:

  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)。

应用程序安全

  对RESTful服务来说,开发1个商洛的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密钥存款和储蓄在加密的平安密钥库中。

 

  伸手不援助的版本

  无状态

能源命名

保险服务的平安

  Authentication(身份验证)指的是肯定给定的呼吁是从服务已知的某人(或有个别系统)发出的,且请求者是他本身所证明的十一分人。Authentication是为着验证请求者的真实性身份,而authorization(授权)是为了印证请求者有权力去实践被呼吁的操作。

  本质上,这几个进度是那般的:

  1. 客户端发起2个呼吁,将authentication的token(身份验证令牌)包涵在X-Authentication
    header中,或者将token外加在乞请的查询串参数中。
  2. 服务器对authorization
    token(授权令牌)实行检讨,并实行验证(有效且未过期),并基于令牌内容分析可能加载认证中央。
  3. 服务器调用授权服务,提供验证主旨、被呼吁财富和必备的操作许可。
  4. 万一授权通过了,服务器将会继续健康运维。

  上边第③步的开支或许会相比较大,不过一旦假若存在三个可缓存的权力决定列表(ACL),那么在产生远程请求前,能够在地面创立贰个授权客户端来缓存最新的ACLs。

用字符串查询参数进行界定

  字符串查询参数被当做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是什么

缓存和可伸缩性

  通过在系统层级消除通过中远距离调用来赢得请求的数额,缓存升高了系统的可扩大性。服务通过在响应中设置headers来增强缓存的能力。遗憾的是,HTTP
1.0中与缓存相关的headers与HTTP
1.1例外,由此服务器要同时协助两种版本。下表给出了GET请求要帮忙缓存所不可不的最少headers集合,并付出了适合的讲述。

HTTP Header

描述

示例

Date

响应重返的日期和时间(CRUISERFC1123格式)。

Date: Sun, 06 Nov 1994 08:49:37 GMT

Cache-Control

一呼百应可被缓存的最大秒数(最大age值)。要是响应不补助缓存,值为no-cache。

Cache-Control: 360

Cache-Control: no-cache

Expires

尽管给出了最大age值,该时间戳(TiguanFC1123格式)表示的是响应过期的年月,也正是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

财富自个儿末了被修改的年华戳(奥德赛FC1123格式)。

Last-Modified: Sun, 06 Nov1994 08:49:37 GMT

  为了简化,那里举一个响应中的headers集合的例证。那是1个简短的对能源拓展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

    排序

  考虑连通性

REST是什么?

  REST架构方式讲述了各类设计准则。那一个用于架构的陈设性准则,最早是由RoyFielding在她的大学生杂文中建议并定义了RESTful风格。(详见http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

  五个统筹准则分别是:

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

  以下是那几个规划准则的事无巨细商讨:

  可缓存

  财富通过链接的可发现性(HATEOAS续)

Body内容中的日期/时间连串化

  有三个简易的不二法门能够解决那么些标题——在字符串中一贯用同一的格式,包含时间片(带有时区音信)。ISO8601时间格式是一个不错的化解方案,它利用了截然增强的时日格式,包涵时辰、分钟、秒以及秒的小数部分(例如yyyy-MM-dd’T’HH:mm:ss.SSS’Z’)。建议在REST服务的body内容中(请求和响应均包罗)使用ISO8601代表全部的日子格式。

  顺便提一下,对于那多少个基于JAVA的劳务以来,DateAdapterJ库使用DateAdapter,Iso8601TimepointAdapter和HttpHeaderTimestampAdapter类能够分外不难地分析和格式化ISO860七日期和时间,以及HTTP
1.1
header(TiggoFC1123)格式。能够从https://github.com/tfredrich/DateAdapterJ下载。

  对于那1个创造基于浏览器的用户界面来说,ECMAScript5正规一开端就含有了JavaScript解析和创立ISO860二十五日期的剧情,所以它应当成为我们所说的主流浏览器所遵守的办法。当然,假诺你要协理那个无法自动解析日期的旧版浏览器,能够行使JavaStript库或正则表明式。这里有多少个能够分析和创办ISO8601时间的JavaStript库:

  http://momentjs.com/

  http://www.datejs.com/

  怎么着时候应该创立贰个新本子?

查询,过滤和分页

  对于大数据集,从带宽的角度来看,限制再次来到的数据量是丰裕主要的。而从UI处理的角度来看,限制数据量也同样主要,因为UI日常只可以展现大数额集中的一小部分数量。在数据集的增长速度不分明的场地下,限制暗中认可再次回到的数据量是很有供给的。以Twitter为例,要博得有个别用户的推文(通过个人主页的时日轴),假使没有特别钦赐,请求暗许只会回到20条记下,即使系统最多能够重回200条记下。

  除了限制重回的数据量,大家还亟需考虑怎么对天意据集实行“分页”或下拉滚动操作。创造数量的“页码”,重返大数额列表的已知片段,然后标出数据的“前一页”和“后一页”——这一行为被叫作分页。其它,大家恐怕也亟需钦命响应少校包含怎么着字段或性质,从而限制重返值的数目,并且大家期待最终可以透过特定值来实行询问操作,并对再次来到值进行排序。

  有二种关键的艺术来还要限制查询结果和实施分页操作。首先,大家得以创造贰个索引方案,它能够以页码为导向(请求中要交给每一页的记录数及页码),或然以记录为导向(请求中央直机关接提交第②条记下和尾声一条记下)来确定重临值的序幕地方。举个例子,那三种方法分别代表:“给出第5页(假若每页有20条记下)的记录”,或“给出第八0到第②20条的笔录”。

  服务端将依照运作体制来举行切分。有个别UI工具,比如Dojo
JSON会采纳模仿HTTP规范使用字节范围。假使服务端帮忙out of
box(即开箱即用效应),则前端UI工具和后端服务时期无需任何转换,那样使用起来会很方便。

  下文将介绍一种方法,既能够帮助Dojo那样的分页方式(在请求头中付出记录的限定),也能支持使用字符串查询参数。那样一来服务端将变得愈加灵敏,既能够运用类似Dojo一样先进的UI工具集,也足以行使简单直接的链接和标签,而无需再为此扩张复杂的花费工作。但如果服务不直接扶助UI效用,可以设想不要在请求头中提交记录范围。

  要尤其提议的是,大家并不引进在全数服务中使用查询、过滤和分页操作。并不是怀有能源都暗中认可协助那一个操作,只有少数特定的能源才支撑。服务和能源的文书档案应当表明怎么样接口帮忙那些复杂的效益。

引言

    过滤

  PUT和POST的创造相比较

可缓存

  在万维网上,客户端能够缓存页面包车型客车响应内容。由此响应都应隐式或显式的概念为可缓存的,若不足缓存则要制止客户端在屡次呼吁后用旧数据或脏数据来响应。管理伏贴的缓存会部分地或完全地除了客户端和服务端之间的相互,进一步改良品质和延展性。

结果的过滤和排序

  针对再次回到结果,还亟需考虑怎么在服务端对数据开始展览过滤和排列,以及如何按内定的顺序对子数据开始展览检索。那一个操作可以与分页、结果限制,以及字符串查询参数filter和sort等相结合,能够兑现强大的数据检索功效。

  再强调一回,过滤和排序都以错综复杂的操作,不需求暗中同意提供给拥有的财富。下文将介绍如何能源必要提供过滤和排序。

 

用范围标记举行限定

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

  Range: items=0-24

  注意记录是从0开端的三番五次字段,HTTP规范中表明了什么选取Range
header来请求字节。也正是说,如果要呼吁数据汇总的第二条记下,范围应该从0早先算起。上述的伸手将会回来前贰十五个记录,若是数据汇总至少有25条记下。

  而在服务端,通过检查请求的Range
header来分明该重临哪些记录。只要Range
header存在,就会有一个简易的正则表明式(如”items=(\d+)-(\d+)”)对其进行分析,来取得要摸索的范围值。

    用范围标记举办限制

  分页

  幂等性

  DELETE

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

    基于范围的响应

回到表征

  正如前方提到的,RESTful接口协理各类能源特点,包蕴JSON和XML,以及被包裹的JSON和XML。建议JSON作为暗许表征,可是服务端应该允许客户端内定别的表征。

  对于客户端请求的性状格式,我们得以在Accept头通过文件扩充名来展开点名,也得以透过query-string等任何格局来钦命。理想图景下,服务端能够支持全数这个点子。然则,今后正式更倾向于经过类似于文件扩充名的不二法门来开始展览点名。由此,建议服务端至少要求帮助采纳文件扩充名的方法,例如“.json”,“.xml”以及它们的卷入版本“.wjon”,“.wxml”。

  通过那种方法,在ULANDI中内定重临表征的格式,能够做实ULacrosseL的可知性。例如,GET
http://www.example.com/customers.xml
将赶回customer列表的XML格式的天性。同样,GET
http://www.example.com/customers.json
将回来1个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格式的能源,将回到1个HTTP
404的荒唐。

  使用HTTP
Accept头被广泛认为是一种更优雅的章程,并且符合HTTP的科班和意义,客户端能够经过那种方法来报告HTTP服务端它们可支撑的数据类型有怎样。可是,为了利用Accept头,服务端要同时支持封装和未封装的响应,你必须完毕自定义的门类——因为那个格式不是规范的门类。那大大扩展了客户端和服务端的纷纷。请参见TucsonFC
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,它大致易读,没有形式和命名空间的界定,换句话来说是无标准的,易于解析。

无状态

  正如REST是REpresentational State
Transfer的缩写,无状态很重庆大学。本质上,那申明了处理请求所需的情况已经包括在央浼笔者里,也有可能是UCRUISERI的一部分、查询串参数、body或底部。UXC60I可以唯一标识各种能源,body中也隐含了财富的转态(或转态变更景况)。之后,服务器将举行拍卖,将有关的情况或能源通过尾部、状态和响应body传递给客户端。

  从事大家这一行业的绝大部分人都习惯使用容器来编制程序,容器中有二个“会话”的定义,用于在八个HTTP请求下维持状态。在REST中,借使要在多少个请求下保持用户情状,客户端必须回顾客户端的持有音讯来成功请求,须要时再也发送请求。自从服务端不要求保险、更新或传递会话状态后,无状态性得到了更大的延展。其它,负载均衡器无需担心和无状态系统里面包车型大巴对话。

  所以状态和能源间有怎么着异样?服务器对于状态,恐怕说是应用状态,所关切的点是在时下对话或请求中要形成请求所需的数目。而财富,或然说是财富气象,则是概念了能源特点的数额,例如存款和储蓄在数据库中的数据。总之,应用状态是是随着客户端和央求的更动而更改的多寡。相反,能源气象对于发出请求的客户端的话是不变的。

  在互连网使用的某一特定岗位上陈设3个回来按钮,是因为它愿意您能按自然的逐一来操作吗?其实是因为它违反了无状态的基准。有好多不遵从无状态原则的案例,例如3-Legged
OAuth,API调用速度限制等。但要么要尽量确认保障服务器中不需求在多少个请求下保持利用状态。

引言

  现今已有多量关于RESTful
Web服务至上实践的相关材质(详见本文最终的相关文献部分)。由于撰文的小时各异,许多资料中的内容是龃龉的。此外,想要通过查看文献来打听这种劳动的进步是不太可取的。为了精通RESTful这一概念,至少须求查阅三到五本有关文献,而本文将能够帮您加快这一进程——吐弃多余的座谈,最大化地提炼出REST的极品实践和标准。

  与其说REST是一套标准,REST更像是一种口径的汇集。除了七个主要的规则外就没有其余的规范了。实际上,就算有所谓的“最佳实践”和正式,但那几个事物都和宗教斗争一样,在频频地衍生和变化。

  本文围绕REST的广阔难题提议了意见和仿食谱式的议论,并因而介绍一些简短的背景知识对成立真实处境下的预生产条件中相同的REST服务提供文化。本文收集了来自其余渠道的音信,经历过叁次次的战败后不断革新。

  但对此REST方式是还是不是必然比SOAP好用仍有较大争议(反之亦然),只怕在有个别情状下仍供给创制SOAP服务。本文在提及SOAP时并未花较大篇幅来谈谈它的争执优点。相反由于技术和行业在不断提升,我们将一连百折不回大家的只要–REST是即刻设计web服务的特级方法。

  第②片段概述REST的含义、设计准则和它的奇异之处。第贰部分列举了部分小贴士来记念REST的服务意见。之后的片段则会更深远地为web服务创制职员提供部分细节的辅助和议论,来促成1个力所能及精晓突显在生产条件中的高品质REST服务。

 

HTTP动词

DELETE

  DELETE很简单理解。它被用来依据U库罗德I标识删除能源。

  例如:

  DELETE http://www.example.com/customers/12345
  DELETE http://www.example.com/customers/12345/orders
  DELETE http://www.example.com/buckets/sample

  当删除成功时,再次来到HTTP状态码200(表示正确),同时会顺便3个响应体body,body中大概带有了剔除项的多少(这会占用部分互联网带宽),恐怕封装的响应(参见下边包车型大巴重返值)。也得以回去HTTP状态码204(表示无内容)表示从没响应体。由此可知,能够回到状态码204意味从没响应体,恐怕再次回到状态码200而且附带JSON风格的响应体。

  依照HTTP规范,DELETE操作是幂等的。假诺你对一个财富进行DELETE操作,能源就被移除了。在能源上翻来覆去调用DELETE最终促成的结果都一模一样:即能源被移除了。但假若将DELETE的操功能于计数器(财富内部),则DETELE将不再是幂等的。如前方所述,只要数据没有被更新,总计和度量的用法照旧可被认为是幂等的。提出非幂等性的财富请求使用POST操作。

  然则,那里有八个有关DELETE幂等性的警示。在八个财富上首次调用DELETE往往会再次回到404(未找到),因为该能源已经被移除了,所以找不到了。那使得DELETE操作不再是幂等的。如果财富是从数据库中除去而不是被简单地方统一标准记为除去,那种情景供给适度让步。

  下表总括出了至关首要HTTP的点子和财富ULANDI,以及引进的再次回到值:

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

 

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

破坏性的改动

  • 改变属性名(例如将”name”改成”firstName”)
  • 除去属性
  • 改变属性的数据类型(例如将numeric变为string,
    boolean变为bit/numeric,string 变为 datetime等等)
  • 转移验证规则
  • 在Atom样式的链接中,修改”rel”的值
  • 在存活的工作流中引入须求能源
  • 更改能源的概念/意图;概念/意图或财富气象的含义分歧于它原本的含义。例如:
    • 1个content
      type是text/html的能源,之前表示的是有着辅助的传播媒介类型的3个”links”集合,而新的text/html则象征的是用户输入的“web浏览器表单”。
    • 多个包涵”end提姆e”参数的API,对财富”…/users/{id}/exams/{id}”表明的意义是学员在10分时间付诸试卷,而新的意义则是考试的预约达成时间。
  • 由此添加新的字段来改变现有的财富。将多少个财富统一为贰个并弃用原来的能源。
    • 有这么五个财富”…/users/{id}/dropboxBaskets/{id}/messages/{id}”和”…/users/{id}/dropboxBaskets/{id}/messages/{id}/readStatus”。新须求是把readStatus财富的品质放到单独的message能源中,并弃用readStatus能源。那将导致messages财富中指向readStatus财富的链接被移除。

  就算下边列出的并不全面,但它交给了有的会对客户端发生破坏性影响的转移类型,那时要求考虑提供1个新财富或新本子。

外加财富

  ETag Header

带有Content-Type的链接

  Atom风格的链接扶助”type”属性。提供丰盛的消息以便客户端能够对特定的版本和内容类型进行调用。

相关文章