RESTful服务至上实践

使Content-Location来加强响应

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

您会效仿到啊?

  • 亮使 npm script 的关键知识要;
  • 操纵 25 单 npm script 实战技能,章节虽少,但是每个章节都是浓缩的;
  • 取得使用 npm script 和各种小器搞定各种前端工程自动化需求;
  • 获得我久久积淀与迭代出来的 npm script 集合,直接行使到项目面临;

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

  REST指导原则有(根据统一接口规范)是application的状态通过hypertext(超文本)来传。这虽是咱们通常所说的Hypertext
As The Engine of Application State
(即HATEOAS,用超文本来当应用程序状态机),我们于“REST是什么”一致节中为关系了。

  根据Roy
Fielding在他的博客中的叙说(http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertextdriven),REST接口中极度要的有是超文本的采取。此外,他尚指出,在被来另相关的音前,一个API应该是可用和可分晓的。也就是说,一个API应当可以经过该链接导航及数码的顺序部分。不建议只有回纯数据。

  不过当下底业界先驱们连从未经常以这种做法,这体现了HATEOAS仅仅在成熟度模型中之使用率还强。纵观众多的服务体系,它们大多返回重新多之多少,而归的链接却坏少(或者无)。这是拂Fielding的REST约定的。Fielding说:“信息的各国一个而寻址单元都携一个地方……查询结果应呈现为一个暗含摘要信息之链接清单,而休是目标往往组。”

  另一方面,简单粗暴地将通链接集合返回会大大影响网络带来富。在实际情形中,根据所欲的基准或应用情况,API接口的通信量要根据服务器响应中超文本链接所蕴藏的“摘要”数量来抵消。

  同时,充分利用HATEOAS可能会见加实现之错综复杂,并对服务客户端起显著的负,这一定给降低了客户端和劳动器端开发人员的生产力。因此,当务之急是一旦平衡超链接服务实践及水土保持可用资源间的题材。

  超链接太小化的做法是以极度可怜限度地缩减客户端和服务器之间的耦合的还要,提高劳动端的可用性、可操纵性和可理解性。这些不过小化建议是:通过POST创建资源并于GET请求返回集合,对于有分页的景后我们会提到。

切合啊群体?

  • 拥抱 无情的推动自动化 开发理念的工程师,不限前端;
  • 感触及 grunt、gulp 之类工具的笨重和紧,想使重新轻量级的化解方案;
  • 相思娱乐转 npm script,不断打磨自己刚技能,提高普通工作效率的同桌;
  • 甘当以自修小册和录制视频使付出的心血而要我喝杯咖啡(19.9最先)的同窗;

    排序

俺们该怎么化解问题?

相比而言,直接采用 npm 内置的 script
机制都于很多开发者证明是双重好的挑选,它会减轻甚至排上面的痛点:你可直接用海量的
npm
包来好而的天职、不需以插件文档和基本功工具文档间来回切换,最要之触发,不以
grunt
之类的构建工具能叫你的技巧栈相对更简便易行,而自当开技术选择是据的中坚规则是简单化,简单才有或容易为旁人上亲手。

使用 npm script 各种基础工具而都可随手拈来,只要你见面用
npmjs.com
去搜索,或者去
libraries.io
上搜索。

也许发生同学会反问,Talk is cheap, show me the data,下面就张图是最好好之印证:

图片 1

更精确的数据是:截止 2017年11月,grunt 插件 6309 个,gulp 插件 3367 个,webpack 插件数量 2174 个,而 npm 包多达 594438 个,并且还在飞速增长

那么 npm script 为什么没没有当构建工具中变成主流呢?可能大部分人觉得使用
npm script
需要很强之命行功底、或者其不够强、或者其不克超越平台。可以充分倚重总责的游说,社区发展到如今,上面的顾虑都是剩下的。

  拍卖跨域问题

互联网大潮及前端社区的蓬勃发展让现代前端项目的繁杂比 5
年前译了累累加倍,前端工作流中吗出现了进一步多工程化的环,比如代码风格检查、自动化测试、自动化构建、自动化部署、服务监控、依赖管理等于。

缓存和可伸缩性

  通过当系层级消除通过远距离调用来赢得请求的数目,缓存提高了系统的不过扩展性。服务通过当应中安装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

可绝不夸张的游说,这仍小册可能是眼下社区中极其完整的把 npm script
和前端工作流相结合并采取到实际项目中的文 + 视频版教程了。

    故范围标记进行界定

什么还快还好之缓解问题?

即时吗是掘金小册《使用 npm script
打造超溜前端工作流》的切入点,我于这按照小册中见面为此
step-by-step 的方式讲解现代前端工作流中的 npm script
用法。即使你是令执行小白,也能够自在与达到,小册会以实际前端项目为底板逐步介绍更高阶的话题。学了就仍小册,你以熟知使用
npm script 打造前端工作流要用的各种小器与技巧。

小册的始末分也 4 篇:

  • 适合门篇:创建同运行 npm script,熟悉和清楚基本套路,分 3 小节;
    • 1.1 创建并运行 npm script 命令
    • 1.2 运行多独 npm script 的各种姿势
    • 1.3 给 npm script 传递参数和增长注释
  • 上阶篇:原来 npm script 还足以如此用?分 3
    小节,介绍生命周期机制、内置和由定义变量的扬言与应用、命令行自动补全等话题;

    • 2.1 使用 npm script 生命周期钩子
    • 2.2 在 npm script 受到动用环境变量
    • 2.3 实现 npm script 命令自动补全
  • 高阶篇:如何管理复杂的 npm script?分 3 小节,介绍;
    • 3.1 让 npm script 跨平台兼容
    • 3.2 用 scripty 管理复杂的 npm script
    • 3.3 用 node/shell 脚本替代复杂的 npm script
  • 实战篇:如何用 npm script 来助前端工作流?分 5 小节;
    • 4.1 监听文件变化并机关运行 npm script
    • 4.2 结合 live-reload 实现活动刷新
    • 4.3 在 git hooks 中运行 npm script
    • 4.4 用 npm script 实现构建流水线
    • 4.5 用 npm script 实现服务自动化运维

以便于大家读小册时越爱上手,自吗小册的每个章节都录制了视频教程(视频下载地址以小册末尾),想打听我视频教程风格以及质地之同桌可以拘留本身专栏的史篇章:styled-components、javascript-async-await。视频目录如下:

图片 2

video-toc.png

  PUT和POST的创建于

俺们面临什么问题?

多数前端工程师的工作流可能还去不起来 gulp、grunt、webpack
这样的重量级构建工具,而是否能运用自如运用这些家伙将再次任务自动化也是工程师素质的根本体现,我自也是这些自动化工具的忠贞粉丝,因为她确实能够协助自己解决问题。但差一点旗磨难后,你恐怕早就像自己同感受及明确的痛点:比如对准插件依赖严重(开发者的自由度受限),插件与底工具文档脱节,调试变的重新复杂等,在马上点达到,我们并无孤独,社区就有人对点的题目作出总结并形容了文章:Why
I left gulp and grunt for npm
scripts。

即便自己要好的亲身经历,我早已接手维护了用了 39 独 gulp
插件的门类,因为路启动于早,部分插件所依靠的底蕴工具版本都比较老,当这些插件所倚的根底工具升级后,gulp
插件本身并没更新的那么尽快,我只好 fork 原仓库去保护内部的版,而当
gulp 发布了新本子后,升级插件更是同样集艰苦的持久战。

冷清思考下来,上面这种复杂其实并没有必要,在软件工程中有只第一的尺度,就是简单性,越是简单的物更可靠,从概率论的角度,任何系统环节更是多稳定性越差。

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

作者简介

自己是王仕军,爱折腾、爱享受的前端老车手,实名在网上生活了 5 年有余,6
年以上前端开发经验(实际是 8 年,哈哈),4
年大型互联网企业办事更;掘金专栏撰稿人;熟知(是的,到今日己还无敢说会)
JavascriptNode.js,对出效率与软件质量产生极致追求。目标是
Be a Power User of Everything

谢谢读到这边,希望自己形容的物对您生出因此!

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

卿要准备什么?

  • Node.js
    运行条件,最好是 v8.x 以上版本,建议使用
    nvm
    来安装,Windows 下的用户可以运用
    nvm-windows;
  • 足据此来输入和执行命令的顶点程序,比如 Mac 下之
    iTerm,或者
    Windows 下的 cmd;
  • 2
    小时之空时间,读了就仍小册,并能团结左手实践,因为纸上得来算觉浅;

因而字符串查询参数进行限定

  字符串查询参数为当作Range
header的替代选择,它以offset和limit作为参数称作,其中offset代表要询问的率先长长的记下编号(与上述的用于范围标记的items第一只数字同样),limit代表记录的不过深条数。下面的例证返回的结果及上述用范围标记的事例一样:

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

  Offset参数的值和Range
header中的好像,也是从0开始计。Limit参数的价值是回到记录之尽特别数据。当字符串查询参数中不指定limit时,服务端应当为有一个短省之太可怜limit值,不过这些参数的动都待以文档中展开验证。

读者报告如何

脚是交目前为止小册收集到之一部分读者报告,对于每位读者的留言,我都见面认真回复,如果你加以了读者交流群,在群里提到的题目,我也会见不遗余力解答。

图片 3

图片 4

图片 5

    支持JSONP

C-S架构

  统一接口使得客户端和服务端相互分开。关注分离意味什么?打独如,客户端不欲仓储数据,数据都留于服务端内部,这样使客户端代码的可移植性得到了提升;而服务端不需考虑用户接口和用户状态,这样一来服务端将越简明容易拓展。只要接口不移,服务端和客户端可独自地展开研发及替换。

  版本控制应以啊级别出现?

非破坏性的修改

  • 在回来的JSON中上加新属性
  • 长指向任何资源的”link”
  • 添加content-type支持的新格式
  • 添加content-language支持之初格式
  • 由于API的奠基人和买主都使处理不同的casing,因此casing的变迁无关紧要

  ETag Header

    弃用

身份验证

  时极度好之做法是使OAuth身份验证。强烈推荐OAuth2,不过她依然居于草案状态。或者选择OAuth1,它完全可以胜任。在某些情况下呢堪挑选3-Legged
OAuth。更多关于OAuth的正式好查看此http://oauth.net/documentation/spec/。

  OpenID是一个增大选择。不过建议将OpenID作为一个外加的身份验证选项,以OAuth为主。更多关于OpenID的专业好查此http://openid.net/developers/specs/。

  始建适当粒度的资源

运用HTTP动词表示有意思

  任何API的使用者能发送GET、POST、PUT和DELETE请求,它们非常充分程度显而易见了所于告的目的。同时,GET请求不可知改任何秘密的资源数量。测量和钉仍可能发,但才会更新数据如果不见面更新由URI标识的资源数量。

书籍

  REST API Design Rulebook,Mark Masse, 2011, O’Reilly Media, Inc.

  RESTful Web Services, Leonard Richardson and Sam Ruby, 2008,
O’Reilly Media, Inc.

*  RESTful Web Services Cookbook, Subbu Allamaraju, 2010, O’Reilly
Media, Inc.*

  REST in Practice: Hypermedia and Systems Architecture, Jim Webber,
et al., 2010, O’Reilly Media, Inc.

  APIs: A Strategy Guide, Daniel Jacobson; Greg Brail; Dan Woods,
2011, O’Reilly Media, Inc.

ETag Header

  ETag
header对于证明缓存数据的新老程度深有因此,同时也助长条件的读取和创新操作(分别吗GET和PUT)。它的价是一个任意字符串,用来代表回到数据的版本。不过,对于返回数据的例外格式,它为得以不同——JSON格式响应的ETag与同一资源XML格式响应的ETag会不同。ETag
header的价好像带有格式的底层域对象的哈希表(例如Java中的Obeject.hashcode())一样简单。建议吗每个GET(读)操作返回一个ETag
header。另外,确保用对引号包含ETag的价值,例如:

  ETag: “686897696a7c876b7e”

 

  Body内容中之日子/时间序列化

  C-S架构

自身该又支持小个本子?

  维护多只不同之本会给工作易得烦、复杂、容易错,而且代价高,对于其它给定的资源,你该支持非越2只版。

  复数

请不支持之版

  当呼吁一个免支持之版号时(包含在API生命周期中早已消失的资源版本),API应当返回一个左的HTTP状态码406(表示不让受)。此外,API还应该返回一个富含Content-Type:
application/json的响应体,其中带有一个JSON数组,用于证明该服务器支持的类。

  #Request

  GET http://api.example.com/users/12345
  Content-Type: application/json; version=999

  #Response

  HTTP/1.1 406 NOT ACCEPTABLE 

  Content-Type: application/json

  [“application/json; version=1”, “application/json; version=2”,
“application/xml; version=1”, “application/xml; version=2”]

哎呀时理应创建一个新本子?

  API开发被的博者都见面打破约定,并最后对客户端起有不良影响。如果您无确定API的改会带来什么的结局,保险起见最好考虑动用本控制。当你在设想提供一个初本子是否方便时,或者考虑针对现有的归来表征进行改动是否肯定能满足急需并被客户端所受时,有这般几只因素而考虑。

    冲范围之应

询问,过滤跟分页

  对于大数据集,从带宽的角度来拘禁,限制返回的数据量是雅关键之。而起UI处理的角度来拘禁,限制数据量也同等要,因为UI通常只能展现大数额集中的相同不怎么片数据。在数据集的增长速度不确定的情事下,限制默认返回的数据量是异常有必不可少的。以Twitter为条例,要博得有用户之推文(通过个人主页的辰轴),如果没有特别指定,请求默认只会回到20漫漫记下,尽管系统最多可回来200条记下。

  除了限制返回的数据量,我们尚待考虑怎么对运据集进行“分页”或下拉滚动操作。创建数量的“页码”,返回大数量列表的就解片段,然后标出数据的“前同一页”和“后一样页”——这同样表现于名分页。此外,我们或也急需指定响应中将包含哪些字段或性能,从而限制返回值的多寡,并且我们意在最后会由此一定值来展开查询操作,并针对回值进行排序。

  有个别种植要的道来还要限定查询结果和履行分页操作。首先,我们得以起一个目录方案,它可以为页码为导向(请求被而为出每一样页的记录数及页码),或者因为记录也导向(请求中一直叫闹第一长条记下及最后一长记下)来确定返回值的起首位置。举个例子,这点儿种办法分别代表:“给起第五页(假设每页有20修记下)的笔录”,或“给有第100顶第120久的记录”。

  服务端将根据运作体制来展开切分。有些UI工具,比如Dojo
JSON会选择模仿HTTP规范行使字节范围。如果服务端支持out of
box(即开箱即用力量),则前端UI工具与后端服务中间无需任何移,这样用起来会那个有益。

  下文将介绍一种植方法,既能够支持Dojo这样的分页模式(在恳求求头中给闹记录的限量),也克支撑以字符串查询参数。这样一来服务端将移得更为灵敏,既可行使类Dojo一样先进的UI工具集,也可以用简易直接的链接和标签,而不论需还为之多复杂的开销工作。但一旦服务不直支持UI功能,可以考虑不要在呼吁求头中被闹记录范围。

  要特别指出的凡,我们连无引进以富有服务遭遇利用查询、过滤和分页操作。并无是有所资源都默认支持这些操作,只有少数特定的资源才支撑。服务和资源的文档应当说明什么接口支持这些扑朔迷离的功用。

  合理的资源名

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。

可缓存

  于万维网上,客户端好缓存页面的应内容。因此应都承诺隐式或显式的定义为而缓存的,若不足缓存则要避免客户端在勤告后为此老数据要污染数据来响应。管理得当的休息存会部分地还是全地除了客户端以及服务端之间的互动,进一步改进性和延展性。

    支持CORS

  经情节商支持版本管理

    破坏性的改

  吁不支持之本

保障服务的安康

  Authentication(身份认证)指的凡认同给定的呼吁是于服务一度知晓的某(或某个系统)发出之,且请求者是他协调所声明的要命人。Authentication是为了证实请求者的实际身份,而authorization(授权)是以印证请求者有权力去实施为求的操作。

  本质上,这个过程是这么的:

  1. 客户端发起一个请,将authentication的token(身份证明令牌)包含在X-Authentication
    header中,或者将token外加以请的查询串参数中。
  2. 服务器对authorization
    token(授权令牌)进行检讨,并进行验证(有效且非过),并因令牌内容分析或者加载认证中心。
  3. 服务器调用授权服务,提供证明中心、被呼吁资源与必备之操作许可。
  4. 比方授权通过了,服务器将会晤持续健康运行。

  上面第三步之开可能会见于坏,但是只要如果存在一个不过缓存的权力控制列表(ACL),那么当有远程请求前,可以以当地创建一个授权客户端来缓存最新的ACLs。

护卫服务之平安

  搜寻有支持的本

资源命名

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

日期/时间拍卖

  如果没有妥善地、一致地拍卖好日期和时吧,这将变为一个特别累。我们常常会面遇上时区的问题,而且由于日期在JSON中凡是为字符串的格式在的,如果非指定统一的格式,那么解析日期也会是一个题材。

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

归来表征

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

劳务版本管理

   坦率地出口,一说到本就会见被人当很艰苦,很辛苦,不绝爱,甚至会见让人口认为难受——因为马上会增加API的复杂度,并同时可能会见指向客户端有有震慑。因此,在API的计划中一经尽量避免多独例外之版。

  不支持版本,不将版本控制作为糟糕的API设计的指。如果您于APIs的计划被引入版本,这迟早还见面受您捉狂。由于返回的数量通过JSON来展现,客户端会由于不同之本子要接受至不同的性能。这样就是会在一些问题,如从内容本身和证明规则者改变了一个业已是的特性的意思。

  当然,我们鞭长莫及避免API可能当好几时候需要转移返回数据的格式和情节,而当时也以导致消费端的组成部分变更,我们当避免进行局部至关重要的调。将API进行版本化管理是免这种根本变更的如出一辙种植有效方法。

  身份验证

HTTP动词

传输安全

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

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

资源命名的反例

  前面我们曾经讨论过局部得体的资源命名的事例,然而有时有反面的例子吗蛮有教育意义。下面是有些无太有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”属性。提供足够的信息以便客户端好对特定的版及情节类型进行调用。

    非破坏性的修改

  HTTP
Headers中之日子/时间序列化

过滤

  以本文中,过滤被定义为“通过特定的标准来确定要要回去的数量,从而减少返回的数”。如果服务端支持一学完整的比较运算符和复杂性的法相当,过滤操作以移得相当复杂。不过我们日常会采取一些简短的表达式,如starts-with(以…开始)或contains(包含)来进展匹配,以保证返回数据的完整性。

  于咱们开谈论过滤的字符串查询参数之前,必须先行清楚为什么而动单个参数而未是基本上独字符串查询参数。从根本上来说是为了减小参数名称的冲。我们早就发生offsetlimitsort(见下文)参数了。如果可能的说话还见面发出jsonpformat标识符,或许还会见生出afterbefore参数,这些都是当本文遇涉嫌过的字符串查询参数。字符串查询中采取的参数越多,就更为可能致参数名称的闯,而使单个过滤参数则会用闯之可能降低到最低。

  此外,从服务端也格外轻就经过单个的filter参数来判定请求方是否要多少过滤效果。如果查询需要的复杂度增加,单个参数将重新具灵活性——可以好建平等模拟功能一体化的询问语法(详见下文OData注释或访问http://www.odata.org)。

  通过引入一组广泛的、公认的分隔符,用于过滤的表达式可以为生直观的款型为运用。用这些分隔符来设置过滤查询参数的价值,这些分隔符所创建的参数名/值对能越来越便于地给服务端解析并提高多少查询的属性。目前一度部分分隔符包括用来分隔每个过滤短语的竖线(”|”)和用来分隔参数称及价值的双料冒号(”::”)。这套分隔符足够唯一,并可大多数动静,同时用其来构建的字符串查询参数为越加便于掌握。下面用因此一个简单的事例来介绍其的用法。假设我们怀念使让名吧“Todd”的用户等发送请求,他们已在丹佛,有着“Grand
Poobah”之称。用字符串查询参数实现之要URI如下:

  GET
http://www.example.com/users?filter="name::todd|city::denver|title::grand
poobah”

  双冒号(”::”)分隔符将属于性名和价值分开,这样属性值就会包含空格——服务端能重复便于地于属于性值中分析出分隔符。

  注意查询参数名/值对面临的特性名要和服务端返回的属性名相匹配。

  简单而有效。有关大小写敏感的题目,要根据具体情况来拘禁,但看来,在并非关心大小写的情形下,过滤效果可以十分好地运作。若查询参数名/值对着的属于性值未知,你吗得以据此星号(”*”)来代替。

  除了简单的表达式和通配符之外,若要进行再扑朔迷离的询问,你不能不使引入运算符。在这种情况下,运算符本身吗是属性值的同等有的,能够为服务端解析,而未是成属性名的平等局部。当需要复杂的query-language-style(查询语言风格)功能时,可参考Open
Data Protocol (OData) Filter System Query
Option说明遭到之询问概念(详见http://www.odata.org/documentation/uriconventions#FilterSystemQueryOption)。

自己怎么告客户端给弃用的资源?

  许多客户端将来作客的资源或当新本子引入后会见受废弃掉,因此,他们需要发出相同种植方法来发现与监察他们之应用程序对遗弃用资源的使。当呼吁一个弃用资源时,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”}

 

  幂等性

叠加资源

应用程序安全

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

 

极致小化链接推荐

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

  对于自服务端返回的特点集合,每个表征应该以它们的链接集合中携带一个尽小之“自身”链接属性。为了有利于分页操作,其它的链接可以在一个独的链接集合中归,必要常常可分包“第一页”、“上等同页”、“下同样页”、“最后一页”等信息。

  参照下文链接格式部分的事例获取更多信息。

    之所以字符串查询参数进行界定

HTTP状态码(前10)

  以下是由于RESTful服务要API返回的极度常用的HTTP状态码,以及有有关其普遍用法的简要说明。其它HTTP状态码不太经常应用,它们要更奇特,要么更高级。大多数劳务套件只支持这些常用之状态码,甚至只有支持中的一样片段,并且它们都能健康干活。

  200 (OK) —— 通常的功成名就状态。表示成功的极常见代码。

  201 (CREATED) ——(通过POST或PUT)创建成功。通过设置Location
header来含有一个对准最新创建的资源的链接。

  204 (NO CONTENT)
—— 封装过的响应没有用,或body中没有另外内容常常(如DELETE),使用该状态。

  304 (NOT MODIFIED)
—— 用于产生原则的GET调用的响应,以压缩带宽的运。
如果采用该状态,那么要为GET调用设置Date、Content-Location和ETag
headers。不分包响应体。

  400 (BAD REQUEST)
—— 用于实践要时可能引起无效状态的形似错误代码。如域名无效错误、数据丢失等。

  401 (UNAUTHORIZED)
—— 用于缺少认证token或证明token无效的错误代码。

  403 (FORBIDDEN)
—— 未授权的用户执行操作,没有权限访问资源,或者是因为一些原因资源不可用(如时间范围等),使用该错误码。

  404 (NOT FOUND)
—— 无论资源存不存在,无论是否出401、403之克,当求的资源找不至经常,出于安全因素考虑,服务器都得以应用该错误码来遮掩。

  409 (CONFLICT)
—— 每当执行要或会见挑起资源撞时以。例如,存在双重的实体,当不支持级联删除时去除根对象。

  500 (INTERNAL SERVER ERROR)
—— 当服务器抛来深时,捕捉到的貌似错误。

 

叠加资源

幂等性

  不要打字面意思来理解啊是幂等性,恰恰相反,这与一些功能紊乱的圈子无关。下面是来源于维基百科的分解:

当计算机科学中,术语幂等用于更全面地叙述一个操作,一次于或累推行该操作有的结果是一模一样的。根据使用的上下文,这可能产生差之意思。例如,在道要子例程调用有副作用的情况下,意味着在率先调用之后让修改的状态吧维持无转移。

  从REST服务端的角度来拘禁,由于操作(或服务端调用)是幂等的,客户端可据此重新的调用而发相同的结果——在编程语言中操作像是一个”setter”(设置)方法。换句话说,就是动多只同的要和使用单个请求效果一样。注意,当幂等操作以服务器上闹相同的结果(副作用),响应本身也许是例外的(例如在多个请求中,资源的状态恐怕会见变动)。

  PUT和DELETE方法给定义也是幂等的。查看http请求中delete动词的警戒信息,可以参考下文的DELETE部分。GET、HEAD、OPTIO和TRACE方法从被定义也平安之方式后,也深受定义也幂等的。参照下关于安全的段落。

    极致小化链接推荐

  通过特征来操作资源

  当客户端收到包含元数据的资源的特性时,在起权力的景下,客户端都控制的足的消息,可以针对劳动端的资源开展删改。

HTTP状态码(前10)

POST

  POST请求时为用于创造新的资源,特别是被用来创造于属于资源。从属于资源就属于其它资源(如大资源)的资源。换句话说,当创建一个初资源时,POST请求发送给父资源,服务端负责用新资源以及老子资源进行关联,并分配一个ID(新资源的URI),等等。

  例如:

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

  当创建成功时,返回HTTP状态码201,并顺便一个职位头信息,其中蕴藏指向最先创建的资源的链接。

  POST请求既未是高枕无忧的同时不是幂等的,因此她叫定义也非幂等性资源要。使用有限独一样的POST请求很可能会见促成创建两单包含相同信息的资源。

  无状态

资源URI示例

  为了以网被插(创建)一个初的用户,我们好运用:

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

 

  读取编号也33245底用户信息:

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

  使用PUT和DELETE来请求相同之URI,可以创新与去数据。

 

  下面是本着产品有关的URI的有建议:

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

  用于创造新的出品。

 

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

  分别用于读取、更新、删除编号也66432底制品。

 

  那么,如何为用户创建一个新的订单也?

  一栽方案是:

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

  这种艺术得以就此来创造订单,但缺少相应的用户数据。

  

  为咱们想啊用户创建一个订单(注意之间的涉及),这个URI可能无敷直观,下面这URI则重复清楚一些:

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

  现在咱们理解它是啊编号33245之用户创建一个订单。

 

  那下面这个要返回的是啊呢?

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

  可能是一个码为33245之用户所创造或者持有的订单列表。注意:我们可遮挡对该URI进行DELETE或PUT请求,因为她的操作对象是一个聚。

 

  继续深入,那下面这URI的伸手而表示什么也?

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

  可能是(为编号33245底用户)增加一个编号吧8769的订单条目。没错!如果运用GET方式要是URI,则会回去这个订单的具有条条框框。但是,如果这些条款与用户信息无关,我们将会晤供POST
www.example.com/orders/8769/lineitems
这个URI。

  从返回的这些条款来拘禁,指定的资源或会见生差不多个URIs,所以我们或吗得而供这么一个URI
GET
http://www.example.com/orders/8769
,用来当匪晓用户ID的状态下基于订单ID来查询订单。

 

  更进一步:

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

  可能只回去跟个订单中之首先个条文。

  现在您应当亮啊是劈层组织了。它们并无是严的规则,只是为了确保于您的劳务受到这些强制的布局能再易于被用户所理解。与具软件开发中之技巧一样,命名是马到成功之最主要。

  

  多看有的API的以身作则并学会控制这些技术,和而的队友一起来宏观而API资源的URIs。这里发出局部APIs的事例:

  • Twitter: https://dev.twitter.com/docs/api
  • Facebook: http://developers.facebook.com/docs/reference/api/
  • LinkedIn: https://developer.linkedin.com/apis

缓存和可伸缩性

  使Content-Location来加强响应

正文主要读者

  该最佳实践文档适用于对RESTful
Web服务感兴趣之开发人员,该服务啊超多单服务之零件提供了比较高的可靠性和一致性。按照本文的指点,可速、广泛、公开地吧内外部客户使用。

  本文中之点拨原则一致适用于工程师们,他们愿意用这些根据最佳实践标准开发的劳务。虽然他们进一步关心缓存、代理规则、监听与平安等相关方面,但是该文档能作为同样卖包含所有品类服务的总指南。

  另外,通过从这些点标准,管理人员了解及开创公共的、提供高稳定的服务所急需花的不竭,他们也只是从中受益。

 

  授权

  POST

经情节商支持版本管理

  以往,版本管理通过URI本身的本号来好,客户端在请的URI中标明要拿走的资源的版本号。事实上,许多充分店如Twitter、Yammer、Facebook、Google等不时于他们之URI里使用版本号。甚至像WSO2这样的API管理工具也会见在它的URLs中求版本号。

  面向REST原则,版本管理技术飞速发展。因为她不分包HTTP规范被置的header,也未支持不过当一个初的资源要概念被引入时才应该添加新URI的意——即版本不是表现形式的变通。另一个不予之说辞是资源URI是未见面随时间改变的,资源就是资源。

  URI应该能够大概地分辨资源——而非是其的“形状”(状态)。另一个纵是得指定响应的格式(表征)。还有局部HTTP
headers:Accept 和 Content-Type。Accept
header允许客户端指定所想还是能支持的响应的传媒类型(一栽要多)。Content-Type
header可分别于客户端和劳动端用来指定要或响应的多寡格式。

  例如,要赢得一个user的JSON格式的数量:

  #Request:

  GET http://api.example.com/users/12345
  Accept: application/json; version=1

  #Response:

  HTTP/1.1 200 OK
  Content-Type: application/json; version=1

  {“id”:”12345″, “name”:”Joe DiMaggio”}

  现在,我们本着同一资源要版本2的数目:

  #Request:

  GET http://api.example.com/users/12345
  Accept: application/json; version=2

  #Response:

  HTTP/1.1 200 OK
  Content-Type: application/json; version=2

  {“id”:”12345″, “firstName”:”Joe”, “lastName”:”DiMaggio”}

  Accept
header被用来代表所想的响应格式(以及示例中之版本号),注意上述两单相同的URI是怎样成功以不同之本子中分辨资源的。或者,如果客户端需要一个XML格式的数码,可以以Accept
header设置为”application/xml”,如果需要的话也可带一个指定的版本号。

  由于Accept
header可以叫安装为允许多传媒类型,在应请求时,服务器将将响应的Content-Type
header设置也极匹配配客户端请求内容的型。更多信息可参照http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.Html

  例如:

  #Request

  GET http://api.example.com/users/12345

  Accept: application/json; version=1, application/xml; version=1

  上述呼吁被,假设服务器支持JSON
和XML格式的乞求,或者简单栽都支持,那么以由服务器来支配最终回到哪种档次的数额。但无论是服务器选择啊一样种植,都见面于应中带有Content-Type
header。

  例如,如果服务器返回application/xml格式的数量,结果是:

  #Response

  HTTP/1.1 200 OK
  Content-Type: application/xml; version=1

  <user>
    <id>12345</id>
    <name>Joe DiMaggio</name>
  </user>

  为了证实Content-Type在发送数据给服务器时的用,这里为有一个据此JSON格式创建新用户的例子:

  #Request

  POST http://api.example.com/users
  Content-Type: application/json;version=1

  {“name”:”Marco Polo”}

  或者,调用版本2底接口:

  #Request

  POST http://api.example.com/users
  Content-Type: application/json;version=2

  {“firstName”:”Marco”, “lastName”:”Polo”}

  合并接口

REST快速提示

  什么时理应创建一个新本子?

  分页

合理的资源名

  合理之资源名称或者路径(如/posts/23设无是/api?type=posts&id=23)可以另行显一个告的目的。使用URL查询串来过滤数据是好好之措施,但非应当用于固定资源名称。

  适当的资源名称为服务端请求提供上下文,增加服务端API的可理解性。通过URI名称分层地查看资源,可以被使用者提供一个祥和的、容易懂的资源层次,以在她们之应用程序上运用。资源名称应当是名词,避免为动词。使用HTTP方法来指定要的动作有,能给事情更是的鲜明。

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

  并不需要在各一个要中还指定版本号。由于HTTP
content-negotiation(内容商)遵循类型的“最佳匹配”方式,所以您的API也应该按这或多或少。根据这同准,当客户端从未点名版本时,API应当返回所支撑之绝早版本。

  还是这例子,获取一个user的JSON格式的多寡:

  #Request

  GET http://api.example.com/users/12345
  Accept: application/json

  #Response

  HTTP/1.1 200 OK
  Content-Type: application/json; version=1

  {“id”:”12345″, “name”:”Joe DiMaggio”}

  相应地,当以POST方式向服务器发送数据经常,如果服务器支持多单不等版本,而要时又没点名版本,和方的事例一样——服务器会将最为小/最早版本的数量包含在body中。为了拓展说明,下面的例子以JSON格式请求一个带有多本资源的服务器,来创造一个新用户(预期会回到版本1):

  #Request

  POST http://api.example.com/users
  Content-Type: application/json

  {“name”:”Marco Polo”}

  #Response

  HTTP/1.1 201 OK
  Content-Type: application/json; version=1
  Location: http://api.example.com/users/12345

  {“id”:”12345″, “name”:”Marco Polo”}

用范围标记进行限

  当用HTTP header而未是字符串查询参数来抱记录之克时,Ranger
header应该通过以下内容来指定范围: 

  Range: items=0-24

  注意记录是从0开始之连日字段,HTTP规范被证了如何利用Range
header来请求字节。也就是说,如果要是乞求数据汇总之第一久记下,范围该从0开始算打。上述的呼吁将见面返回前25单记录,假而数据汇总至少发生25长记下。

  而在服务端,通过检查请求的Range
header来确定该归哪些记录。只要Range
header存在,就见面生一个简单的正则表达式(如”items=(\d+)-(\d+)”)对其开展解析,来得到要摸索的范围值。

    自描述的音

  结果的过滤和排序

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

 

REST快速提示

  (根据上面提到的六单极)不管在技术上是无是RESTful的,这里来一对类似REST概念的提议。遵循它,可以实现重新好、更使得之服务:

REST是什么?

  REST架构方式讲述了六种设计则。这些用于架构的统筹则,最早是由于Roy
Fielding在他的博士论文中提出并定义了RESTful风格。(详见http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm)

  六只计划则分别是:

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

  以下是这些计划则的详尽座谈:

  包裹响应

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暴露不安全之操作——它应有永远都非能够修改服务器上之外资源。

复数

  让咱们来讨论一下复数和“单数”的争议…还没听说过?但这种争议确实在,事实上它可概括为是题材……

  于公的层级结构面临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是立竿见影的。好吧…

 

结果的过滤与排序

  针对返回结果,还索要考虑如何以服务端对数据进行过滤和排,以及怎样以指定的次第对子数据进行检索。这些操作可以与分页、结果限制,以及字符串查询参数filter和sort等相互结合,可以实现强的数据检索功能。

  再强调平等不成,过滤和排序都是扑朔迷离的操作,不待默认提供被有的资源。下文将介绍如何资源用提供过滤和排序。

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

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

  除了上述情节外,HATEOS也意味着,必要的时候链接也可是于含有在返回的body(或头部)中,以提供URI来搜寻对象自我或涉嫌对象。下文将本着斯展开双重详细的论述。

  统一接口是每个REST服务计划时之不可或缺准则。

冲范围的响应

  对一个基于范围的恳求来说,无论是通过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工具或未支持该符号。

破坏性的改动

  • 改变属性名(例如将”name”改成为”firstName”)
  • 删除属性
  • 转移属性的数据类型(例如将numeric变为string,
    boolean变为bit/numeric,string 变为 datetime等等)
  • 反验证规则
  • 以Atom样式的链接中,修改”rel”的价值
  • 在存活的工作流中引入必要资源
  • 改资源的定义/意图;概念/意图或资源状态的意思不同让其原本的含义。例如:
    • 一个content
      type是text/html的资源,之前表示的凡享有支持的传媒类型的一个”links”集合,而新的text/html则表示的是用户输入的“web浏览器表单”。
    • 一个包含”endTime”参数的API,对资源”…/users/{id}/exams/{id}”表达的意思是学生在怪时刻付诸试卷,而初的含义则是考试的预约完毕时。
  • 经过抬高新的字段来转现有的资源。将少单资源统一为一个并弃用原始的资源。
    • 起如此点滴只资源”…/users/{id}/dropboxBaskets/{id}/messages/{id}”和”…/users/{id}/dropboxBaskets/{id}/messages/{id}/readStatus”。新需求是把readStatus资源的特性放到单独的message资源中,并丢掉用readStatus资源。这将造成messages资源遭到指向readStatus资源的链接给移除。

  虽然上面列有底连无圆满,但它们深受来了片晤对客户端起破坏性影响之扭转类型,这时要考虑提供一个新资源或新本子。

正文主要读者

  资源命名的反例

XML和JSON

  建议默认支持json,并且,除非花费很震惊,否则便以支持json和xml。在好图景下,让使用者仅经过改动扩展名.xml和.json来切换类型。此外,对于支撑ajax风格的用户界面,一个为卷入的应是杀有帮衬的。提供一个于包的应,在默认的要么有单独放展名的状下,例如:.wjson和.wxml,表明客户端请求一个深受装进的json或xml响应(请参见下的包裹响应)。

  “标准”中对json的求特别少。并且这些需要就是语法性质的,无关内容格式和布局。换句话说,REST服务端调用的json响应是商量的一律片——在正儿八经被从不相关描述。更多关于json数据格式可以以http://www.json.org/上找到。

  关于REST服务遭遇xml的使用,xml的科班以及预约除了采用语法正确的标签和文本外没有另外的意向。特别地,命名空间不是啊未该是于下在REST服务端的光景文中。xml的回来重新接近于json——简单、容易看,没有模式及命名空间的底细展现——仅仅是多少和链接。如果它比较当下又扑朔迷离的话,参看本节的首先段落——使用xml的老本是震惊之。鉴于我们的经历,很少有人使用xml作为响应。在她于全然淘汰之前,这是最终一个而让得之地方。

  可缓存

  结果限制

  XML和JSON

 

  基于资源

  不同资源要用URI来唯一标识。返回给客户端的特性和资源本身在概念上有所不同,例如服务端不会见一直传送一个数据库资源,然而,一些HTML、XML或JSON数据能显得部分数据库记录,如用芬兰语来表达还是用UTF-8编码则使因请求与服务器实现之底细来支配。

合并接口

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

  应用程序安全

  安全

    链接格式

考虑连通性

  REST的规律之一就是是并通性——通过超媒体链接实现。当于响应中归链接时,api变的再次有从描述性,而以无她经常服务端依然可用。至少,接口本身可以为客户端提供哪些寻找数据的参阅。此外,在经过POST方法创建资源时,还得以头位置包含一个链接。对于响应中支持分页的集,”first”、
“last”、”next”、和”prev”链接至少是怪有效的。

 

分系统

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

无状态

  正如REST是REpresentational State
Transfer的缩写,无状态不行关键。本质上,这标志了拍卖要所欲的状态都包含在呼吁我里,也时有发生或是URI的同片、查询串参数、body或头部。URI能够唯一标识每个资源,body中也带有了资源的转态(或转态变更情况)。之后,服务器将开展处理,将相关的状态或资源通过头部、状态及应body传递让客户端。

  从事我们顿时无异于行之多数总人口犹习惯使用容器来编程,容器中生一个“会话”的定义,用于在多单HTTP请求下维持状态。在REST中,如果一旦当多独请求下维持用户状态,客户端必须概括客户端的富有消息来就请求,必要常常又发送请求。自从服务端不欲保持、更新或传递会话状态后,无状态性得到了又可怜的延展。此外,负载均衡器无需担心与管状态系统里头的对话。

  所以状态与资源间有啊异样?服务器对状态,或者说是应用状态,所关切之接触是于时对话或请被如果完成请求所用的数据。而资源,或者说是资源状态,则是概念了资源特色的数目,例如存储在数据库被之数码。由此可见,应用状态是凡趁客户端以及呼吁的改如果反之多少。相反,资源状态对于发出请求的客户端的话是匪转移的。

  以网络下之有平一定岗位上布置一个归按钮,是为她仰望而能按自然的各个来操作也?其实是坐它们违反了不管状态的尺度。有不少非遵从无状态原则的案例,例如3-Legged
OAuth,API调用速度限制等。但要要硬着头皮确保服务器中不需要在多单请求下维持以状态。

定义

结果限制

  “给有第3顶第55条的笔录”,这种求数据的法和HTTP的字节范围规范更平等,因此我们可以就此它们来标识Range
header。而“从第2漫长记下开始,给出最为多20漫漫记下”这种方法又易于阅读和透亮,因此我们一般会用字符串查询参数的办法来表示。

  综上所述,推荐既支持采取HTTP Range
header,也支撑使用字符串查询参数——offset(偏移量)和limit(限制),然后于服务端对响应结果进行限制。注意,如果又支持就点儿种植艺术,那么字符串查询参数的先级要盖Range
header。

  这里你也许会见有只疑问:“这有限栽办法效果相似,但是回去的数目不完全一致。这会无会见为人歪曲呢?”恩…就是鲜只问题。首先使回的凡,这诚然会给人歪曲。关键是,字符串查询参数看起更加清晰易懂,在构建和剖析时尤其便宜。而Range
header则更多是出于机器来运(偏向于底层),它更是切合HTTP使用标准。

  总之,解析Range
header的做事会多复杂度,相应的客户端在构建请求时也需要开展局部甩卖。而利用单独的limit和offset参数会愈发便于掌握和构建,并且不需要针对开发人员有再度多之渴求。

PUT和POST的始建于

  总之,我们建议采取POST来创造资源。当由客户端来支配新资源有何等URI(通过资源名称或者ID)时,使用PUT:即只要客户端知道URI(或资源ID)是什么,则针对拖欠URI使用PUT请求。否则,当由服务器或劳务端来控制创造的资源的URI时虽然利用POST请求。换句话说,当客户端在创造之前未晓(或无法了解)结果的URI时,使用POST请求来创造新的资源。

安全

  来自维基百科:

一些方法(例如GET、HEAD、OPTIONS和TRACE)被定义也平安之法子,这象征其才于用于信息搜索,而未能够更改服务器的状态。换句话说,它们不会见发生副作用,除了相对来说无害的影响要日志、缓存、横幅广告还是计数服务等。任意的GET请求,不考虑用状态的上下文,都被认为是安的。

  总之,安全意味着调用的方式无会见招副作用。因此,客户端好频繁使用安全的伸手而无用担心对服务端产生其他副作用。这代表服务端必须遵循GET、HEAD、OPTIONS和TRACE操作的安全概念。否则,除了针对消费端产生模糊外,它还见面招Web缓存,搜索引擎和另外活动代理的问题——这将以服务器上有意想不到的结果。

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

  安全的方法被实现啊就念操作。然而,安全并无意味服务器必须每次都归相同之应。

 

DELETE

  DELETE很爱懂。它深受用来冲URI标识删除资源。

  例如:

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

  当去成功时,返回HTTP状态码200(表示对),同时会有意无意一个应体body,body中或许带有了去项之数据(这会占用部分网络带来富),或者封装的响应(参见下的返回值)。也得返回HTTP状态码204(表示管内容)表示没有响应体。总之,可以回去状态码204象征没有响应体,或者返回状态码200而附带JSON风格的响应体。

  根据HTTP规范,DELETE操作是幂等的。如果你针对一个资源开展DELETE操作,资源就让移除了。在资源达到频繁调用DELETE最终致的结果尚且如出一辙:即资源为移除了。但只要将DELETE的操作用于计数器(资源中),则DETELE将不再是幂等的。如前方所陈述,只要数据没有让更新,统计和测量的用法依然可为看是幂等的。建议非幂等性的资源要使用POST操作。

  然而,这里有一个有关DELETE幂等性的告诫。在一个资源上第二不良调整用DELETE往往会回来404(未找到),因为该资源曾让移除了,所以找不交了。这叫DELETE操作不再是幂等的。如果资源是自数据库被去而非是吃略去地记为去,这种状况需要适当让步。

  下表总结发生了要害HTTP的法门和资源URI,以及引进的返回值:

HTTP请求

/customers

/customers/{id}

GET

200(正确),用户列表。使用分页、排序和过滤大导航列表。

200(正确),查找单个用户。如果ID没有找到或ID无效则归404(未找到)。

PUT

404(未找到),除非您想以普集合中更新/替换每个资源。

200(正确)或204(无内容)。如果没找到ID或ID无效则归404(未找到)。

POST

201(创建),带有链接到/customers/{id}的位置头信息,包含新的ID。

404(未找到)

DELETE

404(未找到),除非你想去所有集合——通常不被允许。

200(正确)。如果无找到ID或ID无效则归404(未找到)。

 

网站

  http://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

版本控制应于什么级别出现?

  建议针对单个的资源开展版本控制。对API的片段移,如修改工作流,也许要跨越多个资源的版本控制,以这来防护对客户端有破坏性的震慑。

    根据资源

查询,过滤与分页

    过滤

  旁系统

  书籍

包裹响应

   服务器可以在应中又返回HTTP状态码和body。有成百上千JavaScript框架没有管HTTP状态响应码返回给最终之开发者,这频繁会造成客户端无法根据状态码来确定具体的作为。此外,虽然HTTP规范被发生非常多种响应码,但是反复只是来个别客户端会关注这些——通常大家就于乎”success”、”error”或”failture”。因此,将响应内容与应状态码封装于富含响应信息的特点着,是来必不可少之。

  OmniTI
实验室有这般一个提议,它为誉为JSEND响应。更多信息要参见http://labs.omniti.com/labs/jsend。另外一个提案是由于Douglas
Crockford提出的,可以查此http://www.json.org/JSONRequest.html。

  这些提案在实践中并没了含所有的景。基本上,现在最好好的做法是仍以下属性封装常规(非JSONP)响应:

  • code——包含一个平头列的HTTP响应状态码。
  • status——包含文本:”success”,”fail”或”error”。HTTP状态响应码在500-599内也”fail”,在400-499里吧”error”,其它都为”success”(例如:响应状态码为1XX、2XX和3XX)。
  • message——当状态值为”fail”和”error”时有效,用于展示错误信息。参照国际化(il8n)标准,它可以分包信息号或者编码,可以就含其中一个,或者以富含并就此分隔符隔开。
  • data——包含响应的body。当状态值为”fail”或”error”时,data就包含错误原因要深名称。

  下面是一个返回success的包响应:

{
  "code": 200,
  "status": "success",
  "data": {
    "lacksTOS": false,
    "invalidCredentials": false,
    "authToken": "4ee683baa2a3332c3c86026d"
  }
}

  返回error的包裹响应:

{
  "code": 401,
  "status": "error",
  "message": "token is invalid",
  "data": "UnauthorizedException"
}

  这片个包装响应对应之XML如下:

<response>
    <code>200</code>
    <status>success</status>
    <data class="AuthenticationResult">
        <lacksTOS>false</lacksTOS>
        <invalidCredentials>false</invalidCredentials>
        <authToken>1.0|idm|idm|4ee683baa2a3332c3c86026d</authToken>
    </data>
</response>

  和:

<response>
    <code>401</code>
    <status>error</status>
    <message>token is invalid</message>
    <data class="string">UnauthorizedException</data>
</response>

  自描述的音信

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

HTTP动词

  Http动词主要以“统一接口”规则,并提供给咱们相应之因名词的资源的动作。最重点还是极端常用的http动词(或者称方法,这样叫可能更恰当些)有POST、GET、PUT和DELETE。这些分别对应于创建、读取、更新和去(CRUD)操作。也出诸多其它的动词,但是下频率比较低。在这些下于少之措施中,OPTIONS和HEAD往往使得重新多。

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

  设想连通性

拍卖跨域问题

   我们且闻讯了有关浏览器的同源策略要同源性需求。它依靠的是浏览器只能请时正显示的站点的资源。例如,如果手上方显示的站点是www.Example1.com,则该站点不可知对www.Example.com提倡呼吁。显然这会潜移默化站点访问服务器的计。

  时发出一定量单吃大接受之支撑跨域请求的点子:JSONP和跨域资源共享(CORS)。JSONP或“填充的JSON”是同等栽采取模式,它提供了一个方法要来自不同域中之服务器的多寡。其工作章程是起服务器返回任意的JavaScript代码,而休是JSON。客户端的响应由JavaScript解析器进行分析,而非是直解析JSON数据。另外,CORS是相同种植web浏览器的技艺专业,它为web服务器定义了平栽方法,从而允许服务器的资源得以为无同域的网页访问。CORS被当是JSONP的最新替代品,并且可给有现代浏览器支持。因此,不建议使用JSONP。任何情形下,推荐选择CORS。

排序

  排序决定了起服务端返回的记录之一一。也即是指向响应中的差不多长记下进行排序。

  同样,我们这里只有考虑有比较简单的情状。推荐使用排序字符串查询参数,它包含了同组用分隔符分隔的属于性名。具体做法是,默认对每个属性名以升序排列,如果属于性名有前缀”-“,则按降序排列。用竖线(”|”)分隔每个属性名,这与前边过滤效果中之参数名/值对之做法一样。

  举个例子,如果我们怀念循用户之姓氏和称展开升序排序,而针对雇佣时间进行降序排序,请求将是这么的:

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

  再次强调一下,查询参数名/值对中之性名要和服务端返回的性质名相匹配。此外,由于排序操作比较复杂,我们只有对要之资源提供排序功能。如果需要的话也足以于客户端对小之资源集聚进行排列。

 

  按需编码(可选)

引言

  现今既发恢宏有关RESTful
Web服务至上实践的连锁材料(详见本文最后之系文献有)。由于撰文的时间不一,许多材料被之始末是矛盾的。此外,想如果透过翻文献来打探这种服务的上扬是未太长之。为了了解RESTful这无异于概念,至少需查阅三届五照有关文献,而本文将会帮助你加快这同一经过——摒弃多余的议论,最大化地提炼出REST的最佳实践和业内。

  与其说REST是一致仿标准,REST更如是同等种植标准的联谊。除了六独关键的口径外就不曾任何的科班了。实际上,虽然有所谓的“最佳实践”和正式,但这些东西还与宗教斗争一样,在相连地演变。

  本文围绕REST的宽广问题提出了见识和仿食谱式的讨论,并经过介绍部分简练的背景知识对创建真实地下的优先生产环境面临平等的REST服务提供文化。本文收集了来其他渠道的音信,经历了一次次之挫败后不断改进。

  但对REST模式是否定比SOAP好用本发生较生争(反之亦然),也许在少数情况下遵循需要创造SOAP服务。本文在提及SOAP时并未花较充分篇幅来讨论她的对立优点。相反由于技术与行业在不断进步,我们以继承坚持不懈我们的若–REST是即时设计web服务的特级艺术。

  第一有的概述REST的意思、设计则与它们的例外之远在。第二局部点数了部分略贴士来记忆REST的劳动理念。之后的一些则会再也透地也web服务创建人员提供部分细节的支持和讨论,来实现一个能明白展示在生养环境被的高质量REST服务。

 

授权

  对服务之授权和对任何应用程序的授权一样,没有其他区别。它根据这样一个题目:“主体是不是对加的资源发请求的许可?”这里被闹了简易的老三码数据(主体,资源及认可),因此好爱构造一个支撑这种概念的授权服务。其中中心是受给予资源访问许可的人头或体系。使用这些相似概念,就得啊各国一个主题构建一个缓存访问控制列表(ALC)。

定义

按需编码(可选)

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

  遵从上述条件,与REST架构风格保持一致,能于各种分布式超媒体系统具备梦想之自然属性,比如高性能,延展性,简洁,可变性,可视化,可移植性和可靠性。

  提示:REST架构中的统筹则遭到,只有以需要编码为而卜项。如果某个服务违反了其他随意一码则,严格意思上未可知称之为RESTful风格。

 

返回表征

  正而前方提到的,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,它概括容易读,没有模式和命名空间的范围,换句话来说是任正规的,易于解析。

分页

  上述办法经过请求方指定数据集的限制来限制返回结果,从而实现分页功能。上面的例证中累计发生66长达记下,如果各页25长长的记下,要显得第二页数据,Range
header的情如下:

  Range: items=25-49

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

  GET …?offset=25&limit=25

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

  Content-Range: 25-49/66

  于大部景象下,这种分页方式都没有问题。但偶尔会发出这种情形,就是若回来的记录数据无法直接表示成数据汇总之行号。还有就是是起把数据集的别快,不断会有新的多少插入到数码集中,这样必然会导致分页出现问题,一些重新的数量也许会见出现在不同之页中。

  按日期排列的数据集(例如Twitter
feed)就是同等种常见的景。虽然你要么得本着数码进行分页,但有时候用”after”或”before”这样的第一字连和Range
header(或者和字符串查询参数offset和limit)配合来贯彻分页,看起会愈从简易亮。

  例如,要博取给定时间戳的前头20久评论:

  GET
http://www.example.com/remarks/home\_timeline?after=&lt;timestamp&gt; 

  Range: items=0-19

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

*  Range: items=0-19*

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

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

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

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

  如果要时莫点名要回来的数据范围,服务端返回了平组默认数据或者限的卓绝酷数据集,那么服务端同时为理应当回结果遭到含有Content-Range
header来和客户端进行确认。以地方个人主页的日轴为条例,无论客户端是不是指定了Range
header,服务端每次都只是回去20条记下。此时,服务端响应的Content-Range
header应该包含如下内容:

  Content-Range: 0-19/4125

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

    本身争告客户端给弃用的资源?

Body内容遭之日子/时间序列化

  有一个简约的法可缓解这些问题——在字符串中始终用平等的格式,包括时间片(带有时区信息)。ISO8601时间格式是一个没错的解决方案,它使了完全增强的辰格式,包括小时、分钟、秒和秒的小数部分(例如yyyy-MM-dd’T’HH:mm:ss.SSS’Z’)。建议于REST服务的body内容被(请求与应均包括)使用ISO8601代表有的日期格式。

  顺便取一下,对于那些基于JAVA的劳动以来,DateAdapterJ库使用DateAdapter,Iso8601TimepointAdapter和HttpHeaderTimestampAdapter类可以非常容易地剖析及格式化ISO8601日期与时,以及HTTP
1.1
header(RFC1123)格式。可以从https://github.com/tfredrich/DateAdapterJ下载。

  对于那些创建基于浏览器的用户界面来说,ECMAScript5正经一开始便包含了JavaScript解析和开创ISO8601日期的情节,所以她应当成为我们所说的主流浏览器所遵循的点子。当然,如果你要支持那些不能自动解析日期的旧版浏览器,可以行使JavaStript库或正则表达式。这里发生几乎独可以分析及创办ISO8601时间之JavaStript库:

  http://momentjs.com/

  http://www.datejs.com/

  GET

    自己应该而且支持小个版本?

日子/时间拍卖

链接格式

  参照整个链接格式的正式,建议遵守一些近乎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

    由此特征来操作资源

劳务版本管理

  传安全

创立适当粒度的资源

  同开始,系统受到模拟底层应用程序域或数据库架构的API更便于为创造。最终,你会盼以这些劳动都成到一起——利用基本上起底层资源减少通信量。在创建独立的资源之后再创更可怜粒度的资源,比由更甚的共同集中创建于充分粒度的资源更容易有。从部分略带的爱定义的资源开始,创建CRUD(增删查改)功能,可以假设资源的创办变得重复便于。随后,你得创造这些根据用例和削减通信量的资源。

  网站

招来来支持之本

  利用HTTP动词表示有含义

弃用

  Deprecated(弃用)的目的是故来证实资源对API仍然可用,但当明天会见无存并转移得无可用。顾:弃用的时长将出于弃用政策决定——这里连没有给有概念。

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

 

  DELETE

REST是什么

  资源URI示例

  PUT

引言