公海赌船网站根据资源。天天运动上前了书店。这次FOCAL Spark Silver

本文主要读者

公海赌船网站 1

提起国外耳机品牌而首先想到的是啊?德国底森海赛尔、拜亚动力或者奥地利底AKG?亦或者美国的Beats?其实多年来,一些小众品牌的耳机也于HiFi发烧友慢慢挪动上前寻常消费者,丹麦的B&O就是里面的代表。今天牵线的FOCAL劲浪是1980每当法国建的大名鼎鼎音响品牌,那么她们生产的即款Spark
Silver 入耳式通话耳机的变现又哪也?

引言

学后的小巷子里,有雷同家不起眼的多少书店。书店的门户小窄的,窗户小小的,如果不过细看,还当真发现不了啊。再探里面,就重新给人瞠目结舌啦。店里唯一的照明光源,是一致杯旧旧的吊灯,还是那种特别老的钨丝灯泡,灯光昏黄微弱,别说看开了,在这样的灯光下,只怕看清书名都非是千篇一律项容易的从事。噢,对了,书店还出个意想不到之名,叫——考试专用书店。

FOCAL的出品最初专注于高端市场,价格比较高昂。作为主打性价比的一律款款耳塞,Spark
Silver
的包装无想像中的法国性感,黑白的简单设计反而科技感十足。对了,FOCAL的出品于境内的行货代理是锦艺国际,买的下需要小心下。

REST是什么

假如无是盖心不在焉走错了路程,天天也未会见活动及这边来。看到门楣上不大的商标,天天这就给抓住了。他巧为考试的政工发愁呢!老爸说了,这次如果再考试得像上次同等差劲,就如将他的微处理器给没收了,还要把生单月之零花钱减半。对天天来说,这简直是天不胜之死讯,更糟糕的凡,他从不怕从来不主意堵住这种业务的发。因为修对他的话实在是平宗很,哦,不,是蛮痛的转业。他抓不懂得那些简单的英文字母为什么做一下即使改成了一个单词,换一下梯次就以成为了另外一个单词。还有数学,那么深之数字相加,他的指了无敷用好啊!乘法也蛮看不惯,还要背啊就法口诀,他历来不怕记不停止。总之,如果让他评选的话语,考试和学得分别占据世界上最惨痛之业务榜单的第一称呼以及第二誉为。老师说,天天的小脑瓜还是特别聪明之,也许只是没搜对上学方式而已。可是,什么才是针对性的求学道也?唉,真是越来越想更憋气。

开拓包裹内部的很简练,但耳机盒包装内衬部分做工不错。耳机保护之好好与否无见面格外麻烦用出去。

  合接口

取得在死马当活马医的心情,天天活动上前了书店。

打包清单除了耳机外,包含说明书、干燥剂、三组硅胶套(S/M/L),其中一付既M号被装置于耳机上和一个耳机收纳盒。

    依据资源

“欢迎来到考试专用书店。”缩在柜台后面正在看报纸的总人口懒懒地于天天打招呼。他整整人口几乎都吃报纸挡住了,只发一至绒绒的毛线帽子。

耳机作为一个习俗产品并无例外,这次FOCAL Spark Silver
作为同样暂缓符合门级耳塞主打听感、配色和安全带舒适感。

    经过特色来操作资源

“请问,这里……有足辅助人……考来好成绩的开吗?”天天还犹豫豫地问。

作日常通勤佩戴的耳塞,就至关重要之虽是着装舒适与线材不绕。Spark
Silver采用的面线,线材偏硬,实际感受受到好少打结。

    起描述的音讯

“你想如果啊门课的题啊?”对方声音还懒洋洋的。

得益于铝合金外壳,虽然圆柱形的外观比较传统,但耳塞的轻重大轻,佩戴感还不错。腔体边缘有普用了CNC切边加工之拍卖,拿起来为不割手。对比手头有境内无绳机厂家的贴牌耳机,Spark
Silver的大体隔效果相当对。

    超媒体即以状态引擎(HATEOAS)

“英语,还发生数学,当然,最好,最好,每一样派系课还有。”天天有些羞涩,低着头,声音也遏制得低低的。

耳机插口采用的3.5mm规格,不得不说这样设计有些赶不达标潮流了。毕竟耳机上之3准键线控主打的凡手机放歌,而眼下底主流的旗舰手机还换上了Type-c和
Lighting接口。随机附赠一长长的转接线或是只是的工作。

  无状态

“什么!每一样家课!”坐于柜台后面的“人”忽然放下报纸,站了起。呀,原来是一律独自特别花猫!

线控部分共有三单按键,支持安卓、iOS和windows。手感不错,盲操也非常轻松。功能包括:来电时之接听/挂断;听音乐时的广播/暂停和切换音乐。线控上之高保真麦克风实测不错,打电话时音质清晰。按键的机能并无保证在具备品牌手机上且能够一心落实,本人的小米6手机使用完全没有问题,其他的哪怕需要活动测试了。

  可缓存

随时目瞪口呆地看在她,简直无法相信自己的眸子。

当同样慢耳机,最要害的当然就是听歌了。Spark
Silver的单元采用的凡9.5毫米的钕磁铁动圈,灵敏度103dB,阻抗16Ω,参数上来拘禁属于好推的。并经过乌托邦Utopia调音团队之调试。这个团伙之前专注劲浪FOCAL一些高端产品的调音,实际听感还是要命有特色的。

  C-S架构

“这么盯在他人看只是免礼貌呀,”猫先生慢吞吞地动及时刻面前,“跟自身来吧。”

戴上这款耳机听歌时,第一发就是是响足够“大”,足够纯净,这样拉动的直观感受就是增多配一些主打音质的手机来听歌,也堪获对的听感。譬如阿黛尔,蔡健雅这些女声歌曲时,人声部分小毒,有丝惊艳感。低频部分的氛围感非常好,干净纯粹,如果平常喜欢听live
版歌曲的相会一定有觉得。

  分系统

无时无刻都犹豫豫地圈正在猫先生,不了解自己是休是应该和上来。

掩映手头的索尼NW-ZX100播放器听有的无害歌曲时,发现在数上显现吧无可非议,生声音清晰明了,打击乐的伴奏令人记忆深刻,没有有入门耳机常见的毛刺锯齿感。至于进一步是否生升级,还欲煲一段时间再望。

  按需编码(可选)

以天天犹豫的时段,猫先生都通过书架,到了书店最深处的等同鼓小门前。它回头看看天天,似乎以询问,不跟上来吧?

总就款耳机虽然是一个相对小众的品牌,外观和设计也中规中矩,但实则感受一段时间后您会特别生同丝惊喜感。不错的人声表现,轻盈舒适的佩戴感,很少缠绕的线材和各级操作系统兼容的线控,让这款类似中庸的耳塞成为寻常听歌的笃定伙伴,至于官方宣传之时尚感和配色,我立边拿出保留意见,毕竟很多辰光大众的审美其实还是离不少底。

REST快速提示

天天犹豫再三,最后要毅然跟着猫先生挪上前了那么扇小家。

  采用HTTP动词表示有含义

天天怎么呢从没能想到,在那么扇不起眼的稍门背后,居然隐藏着一个那么奇异的世界。

  客观之资源名

汝瞧,一进家,有啊事物便以长者压顶的势投下大大的同一块阴影。抬头看去,原来是比如说房子一样大之繁花。天天的口张得大大的,简直能塞下一个鸡蛋了。这么大的繁花,他可算见所未见,闻所不闻哪。天天兴奋地于花株之间跑来跑去,绕在这改变几环,再绕在老大转几绕,一刻也停不下来。再看猫先生,它在前面不慌不忙地运动在,显然对周围的任何还司空见惯了,一点未看蹊跷。

  XML和JSON

“不克仅仅所以眼睛看,记得还要因此好的耳根听哟。”猫先生就此爪子点点自己之耳朵。

  创立适当粒度的资源

无时无刻就才发现,他每于平株花下经过的时光,花朵就见面发好听的声,有时是red,有时是blue,有时候是green,具体产生非常单词的读音,则要拘留他是自从同枚什么颜色之花下面经过了。除了颜色以外,还有许多旁的单词,sun、cake、cat……凡是出现于英语课本上的单词,在此间都能听到,当然,在花们念出这些单词的上,相对应之单词形象都见面并发在它硕大的花瓣儿上。

  设想连通性

无时无刻看好玩儿极了,他一如既往全副又平等一体地随着花儿们读,不一会儿他虽记住了有着的单词。每当他读来一个单词,他都能这想起来相应的像为。这大概就老师说了之联想记忆法吧。也未曾那么难嘛!天天心里有头小得意。

定义

尽管当这时,地面忽然传来阵阵痛的震颤,还有“啪,啪”的音一下一眨眼地响起,声音更接近,越来越贴近,像是某种体型高大之动物在走近。

  幂等性

重看看猫先生,他似乎被吓够呛了,神色慌张地对准天天喝:“跑,快跑!”说罢,猫先生便疯狂奔起来。不明所以的随时也不得不跟着猫先生一起飞奔。

  安全

旁边的花丛被同特大大的鼻子拱开,紧接着,一仅仅足足有大象那么大之老鼠从后走了出。再看看猫先生,此刻他吗顾不上什么形象了,整个身子都隐藏于地上,四肢并用,脚底生风地逃命呢。

HTTP动词

老鼠显然发现了猫先生,也落起四爪在后疯狂追赶起来。

  GET

即时大老鼠越来越近,越来越近,眼看又过一会儿不怕会遇见他们了。谁知道不幸之事就在这起了——前面居然没路了!只生一个吃蟹的挺耳坠子一样的山头堵住的卡子。关卡旁边还有几鸣数学题。看样子要把数学题解出来,把对答案写以门边的空白板上,门才见面打开。

  PUT

无时无刻看在那几鸣数学题,真是一个头颅两单非常,这要是水到渠成什么时才能够开出来吧。看来只有等着给那个老鼠吃少了。天天绝望地闭上了双眼。不过还从未当他管眼闭上,他便受猫先生一样把拉进了蟹钳门里。原来猫先生就快答完题写出了对答案,门也早已打开了。

  POST

有关那不过怪老鼠嘛,它刚其实走得极度抢了,一下子从来不能刹住脚步,整个头部都遇到在了蟹钳门上,鼻子都赶上流血啦。

  PUT和POST的创立于

蟹钳门后面,是其他一个异之社会风气。怎么个奇异法呢?原来呀,这里的树上结出来的莫单独生收获,还有为数不少别的东西。比如,面包啦,甜甜蜜蜜圈啦,还有棉花糖啊,它们中间唯一相同之地方便是貌都如某个阿拉伯数字。不过这些数字看上去只是于课本上的那些可爱多矣。天天开心地挥发至培养底下,抬头看在树上的数字,嘴里还嘟囔地算着几加几顶为几,猫先生虽然耐心地于干听在,还时常地传授给天天有算的办法和技术,没过多格外一会儿,天天就熟练掌握了数字的加法。这会,别说凡是一百以内之加法了,就是少百坐内的或是也麻烦休停歇客了。除了加法,还有乘法除法,天天也都依次掌握了。

  DELETE

为了帮扶天天巩固所模拟的知识,猫先生还亲身给天天发生了同样卖试卷也。结果而怀疑怎么在?天天还全部都报对了,得矣一百瓜分也。对客来说,这简直是不可想像的。此刻之随时看,如果列有一致卖世界上无与伦比开心之作业的排行来说,学习与试验肯定占据第一称以及亚称。

资源命名

为感谢猫先生,天天一样抹脑倒来了书包里存有的传家宝,什么变形金刚啊,小汽车啊,还有刮刮卡什么的。可是猫先生什么还没有使,只是收生了相同片小的巧克力作为报酬。或许,它是同一单纯爱吃巧克力的猫吧。离开书店的上,天天告诉猫先生,下次肯定要是带动一块最特别无比香的巧克力被其。可是猫先生听到后只是发自了微笑,什么吧未曾说。

  资源URI示例

该校的考试成绩很快出来了。从前接连考试不及格的天天,这次破天荒地每门功课都考了八十大多分。天天的爸爸妈妈别提有差不多喜欢了。爸爸还奖励吃了随时一样贵新的笔记本电脑呢。更为重要的凡,从这以后,天天像是易了一个总人口似的,学习对他的话再也不是什么困难的事,考试就又无是了。或许便像老师所说之那么,天天就找到了属他自己之读方式。

  资源命名的反例

新生,天天又至学府后的小巷子里去了几不善,他说过如果送一样片最老无比美味的巧克力被猫先生的,可是那里分明是均等切片废墟,根本不怕没啊书店。

  复数

归来表征

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

    不过小化链接推荐

    链接格式

  包装响应

  处理跨域问题

    支持CORS

    支持JSONP

询问,过滤与分页

  结果限制

    就此范围标记进行限制

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

    基于范围的响应

  分页

  结果的过滤和排序

    过滤

    排序

劳动版本管理

  经情节商支持版本管理

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

  恳请不支持之本

  哎时候该创建一个初本子?

    破坏性的修改

    非破坏性的改动

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

  以Content-Location来提高响应

  带有Content-Type的链接

  招来有支持的版本

    自家应当同时支持小只版本?

    弃用

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

日期/时间拍卖

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

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

维护服务的安全

  身份验证

  传安全

  授权

  应用程序安全

缓存和可伸缩性

  ETag Header

HTTP状态码(前10)

外加资源

  书籍

  网站

 

本文主要读者

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

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

  另外,通过打这些点标准,管理人员了解及开创公共的、提供高稳定性的劳务所欲花费的努力,他们啊可从中受益。

 

引言

  现今一度发出雅量关于RESTful
Web服务至上实践的系材料(详见本文最后的相关文献有)。由于撰文之时空各异,许多素材中的始末是矛盾的。此外,想如果经过查看文献来打听这种服务之进步是未绝长的。为了打探RESTful这同概念,至少得查阅三交五依照有关文献,而本文将能够帮助您加速这无异经过——摒弃多余的讨论,最大化地提炼出REST的顶尖实践和正规。

  与其说REST是均等效标准,REST更如是相同栽口径的集纳。除了六独重要之尺码外即从来不其余的正儿八经了。实际上,虽然有所谓的“最佳实践”和专业,但这些东西都和宗教斗争一样,在频频地演变。

  本文围绕REST的大面积问题提出了意见跟仿食谱式的讨论,并透过介绍部分简练的背景知识对创建真实处境下的先行生产条件遭到千篇一律的REST服务提供文化。本文收集了自其它渠道的消息,经历过一次次的挫折后不断改进。

  但对此REST模式是否定比SOAP好用本发生比较充分争(反之亦然),也许在某些情况下遵循用创造SOAP服务。本文在提及SOAP时并未花较充分篇幅来谈谈其的对立优点。相反由于技术以及行在不断进步,我们用连续坚持我们的设–REST是这筹web服务之特级方法。

  第一组成部分概述REST的意义、设计则和她的特殊之处在。第二有的点数了片略贴士来记忆REST的劳动意见。之后的一对则会再也透地啊web服务创建人员提供部分细节之支撑以及讨论,来实现一个会公开展示在生条件中的大质量REST服务。

 

REST是什么?

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

  六独计划则分别是:

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

  以下是这些规划则的详实座谈:

联接口

  统一接口准则定义了客户端与服务端之间的接口,简化和分手了框架结构,这样一来每个片还不过单独演化。以下是接口统一之季只尺码:

  基于资源

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

  通过特色来操作资源

  当客户端收到包含元数据的资源的特性时,在发出权力的情况下,客户端都掌握的够用的信,可以对劳务端的资源拓展删改。

  自描述的音讯

  每条消息还带有足够的数码用于确认信息该如何处理。例如要由网络媒体类型(已了解之若MIME类型)来确认要调用哪个解析器。响应同样也表明了它的缓存能力。

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

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

  除了上述内容他,HATEOS也代表,必要之时段链接也可是让含有在返回的body(或头部)中,以供URI来索对象自我要涉对象。下文将对准是进行重新详细的阐释。

  统一接口是每个REST服务统筹时的必要准则。

无状态

  正如REST是REpresentational State
Transfer的缩写,无状态大要紧。本质上,这标志了拍卖要所要的状态都包含在请我里,也出或是URI的一模一样片、查询串参数、body或头部。URI能够唯一标识每个资源,body中也饱含了资源的转态(或转态变更情况)。之后,服务器将开展处理,将相关的状态或资源通过头部、状态和应body传递给客户端。

  从事我们就等同行之大多数口犹习惯用容器来编程,容器中出一个“会话”的概念,用于在多单HTTP请求下维持状态。在REST中,如果如当多独请求下维持用户状态,客户端必须概括客户端的保有消息来形成请求,必要时又发送请求。自从服务端不欲保障、更新或传递会话状态后,无状态性得到了再也可怜之延展。此外,负载均衡器无需担心和任状态系统中的对话。

  所以状态和资源间发生什么差别?服务器对状态,或者说是应用状态,所关注的触及是当手上对话或要中只要水到渠成请求所欲的数量。而资源,或者说是资源状态,则是概念了资源特点的数目,例如存储于数据库中之数码。由此可见,应用状态是凡趁客户端和乞求的转移而改变之多寡。相反,资源状态对于发出请求的客户端的话是勿换的。

  于网络采用的某某同特定岗位及摆一个回按钮,是盖其想您会按自然之逐条来操作也?其实是为它违反了不管状态的尺度。有成千上万非守无状态原则的案例,例如3-Legged
OAuth,API调用速度限制等。但还是如尽可能保证服务器遭受不需以差不多只请求下维持利用状态。

可缓存

  在万维网上,客户端好缓存页面的响应内容。因此应都许诺隐式或显式的定义为可缓存的,若不足缓存则使避客户端在勤告后用原来数据或者污染数据来响应。管理得当的休养生息存会部分地要全地除了客户端和服务端之间的互相,进一步改善性与延展性。

C-S架构

  统一接口使得客户端以及服务端相互分开。关注分离意味什么?打独比方,客户端不需仓储数据,数据还留给在服务端内部,这样叫客户端代码的可移植性得到了晋升;而服务端不需要考虑用户接口及用户状态,这样一来服务端将更简约容易拓展。只要接口不转移,服务端和客户端好独立地进行研发和替换。

支行系统

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

按需编码(可选)

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

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

  提示:REST架构中的设计则遭到,只有按需编码为可选项。如果有服务违反了别随意一宗则,严格意思上无克称之为RESTful风格。

 

REST快速提示

  (根据地方提到的六独标准化)不管在技术上是休是RESTful的,这里有一部分像样REST概念的建议。遵循它,可以兑现又好、更使得之劳动:

利用HTTP动词表示有意思

  任何API的使用者能发送GET、POST、PUT和DELETE请求,它们非常非常程度明显了所让要的目的。同时,GET请求不可知转任何秘密的资源数量。测量与跟踪仍可能来,但仅见面更新数据要未会见更新由URI标识的资源数量。

成立的资源名

  合理之资源名称或路径(如/posts/23比方未是/api?type=posts&id=23)可以重引人注目一个求的目的。使用URL查询串来过滤数据是甚好之办法,但无该用于固定资源名称。

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

XML和JSON

  建议默认支持json,并且,除非花费很震惊,否则就是又支持json和xml。在精彩状态下,让使用者仅透过变更扩展名.xml和.json来切换类型。此外,对于支撑ajax风格的用户界面,一个让包裹的响应是很有扶持的。提供一个为卷入的响应,在默认的要发独立放展名的情事下,例如:.wjson和.wxml,表明客户端请求一个受包裹的json或xml响应(请参见下的包响应)。

  “标准”中针对json的要求非常少。并且这些需求光是语法性质的,无关内容格式和布局。换句话说,REST服务端调用的json响应是协商的一样局部——在正儿八经中没有有关描述。更多关于json数据格式可以当http://www.json.org/上找到。

  关于REST服务中xml的采取,xml的专业与预约除了采取语法正确的价签以及文本外没有另外的意图。特别地,命名空间不是啊不该是让采用以REST服务端的前后文中。xml的归来重新类似于json——简单、容易看,没有模式和命名空间的细节表现——仅仅是数额与链接。如果其比较就再次复杂的话,参看本节的第一段子——使用xml的资本是惊人的。鉴于我们的经验,很少有人利用xml作为响应。在其让统统淘汰之前,这是最后一个可被肯定的地方。

缔造适当粒度的资源

  同开始,系统遭到效仿底层应用程序域或数据库架构的API更易于让创造。最终,你晤面期待将这些劳务还做及一块——利用基本上件底层资源减少通信量。在开创独立的资源后再也创更要命粒度的资源,比由再可怜的联手集中创建于生粒度的资源更是爱有。从一些有点之轻定义之资源开始,创建CRUD(增删查改)功能,可以要资源的创造变得又爱。随后,你可创造这些根据用例和减少通信量的资源。

设想连通性

  REST的规律之一即是并通性——通过超媒体链接实现。当当响应中回到链接时,api变的重新兼具从描述性,而在尚未它经常服务端依然可用。至少,接口本身可以啊客户端提供哪些寻找数据的参阅。此外,在通过POST方法创建资源时,还可以行使头位置包含一个链接。对于响应中支持分页的汇,”first”、
“last”、”next”、和”prev”链接至少是很管用的。

 

定义

幂等性

  不要从字面意思来掌握啊是幂等性,恰恰相反,这跟一些功能紊乱的领域无关。下面是来源于维基百科的说明:

以电脑科学中,术语幂等用于更周全地叙述一个操作,一糟糕还是累实践该操作发生的结果是一模一样的。根据使用之上下文,这恐怕出差的意思。例如,在道要子例程调用装有副作用的状态下,意味着在首先调用之后让改动的状态吧保不转换。

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

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

安全

  来自维基百科:

有艺术(例如GET、HEAD、OPTIONS和TRACE)被定义也安之法门,这意味它只让用于信息寻找,而无克改服务器的状态。换句话说,它们不见面起副作用,除了相对来说无害的影响要日志、缓存、横幅广告还是计数服务等。任意的GET请求,不考虑使用状态的上下文,都吃看是高枕无忧之。

  总之,安全意味着调用的点子不见面滋生副作用。因此,客户端可频繁用安全的要而不用担心对服务端产生其他副作用。这象征服务端必须遵GET、HEAD、OPTIONS和TRACE操作的平安概念。否则,除了针对消费端产生模糊外,它还会见导致Web缓存,搜索引擎和其它活动代理的问题——这将于服务器上发生意想不到的产物。

  根据定义,安全操作是幂等的,因为它于服务器上起同样之结果。

  安全之点子吃实现吗单独读操作。然而,安全并无表示服务器必须每次都回去相同的应。

 

HTTP动词

  Http动词主要按“统一接口”规则,并提供被我们相应之因名词的资源的动作。最重点还是最好常用之http动词(或者叫做方法,这样名可能更恰当些)有POST、GET、PUT和DELETE。这些分别指向应于创建、读取、更新和去(CRUD)操作。也发出诸多别样的动词,但是用频率比较小。在这些以于少之章程吃,OPTIONS和HEAD往往使得重新多。

GET

  HTTP的GET方法用于检索(或读取)资源的数码。在是的呼吁路径下,GET方法会返回一个xml或者json格式的多少,以及一个200底HTTP响应代码(表示对返回结果)。在错情况下,它通常返回404(不有)或400(错误的乞求)。

  例如:

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

  按照HTTP的设计规范,GET(以及附带的HEAD)请求单用于读取数据而未改动多少。因此,这种以方法受看是安全的。也就是说,它们的调用没有数修改或者染的风险——调用1糟及调用10赖还是尚未为调用的成效等同。此外,GET(以及HEAD)是幂等的,这意味使用多独一样的要和用单个的请最终都装有相同的结果。

  不要通过GET暴露不安全的操作——它应当永远都未能够修改服务器上的其余资源。

PUT

  PUT通常被用于创新资源。通过PUT请求一个已解的资源URI时,需要在伸手的body中隐含对原来资源的创新数据。

  不过,在资源ID是出于客服端而未服务端提供的动静下,PUT同样好于用来创造资源。换句话说,如果PUT请求的URI中蕴含的资源ID值在服务器上无有,则用来创造资源。同时要的body中须含有要创建的资源的多少。有人认为就会发歧义,所以只有真的用,使用这种措施来创造资源应该被慎用。

  或者我们呢得以body中提供由客户端定义的资源ID然后使用POST来创造新的资源——假设请求的URI中未分包要创的资源ID(参见下POST的一对)。

  例如:

*  PUT http://www.example.com/customers/12345*
  PUT http://www.example.com/customers/12345/orders/98765
  PUT http://www.example.com/buckets/secret\_stuff

  当使用PUT操作更新成功时,会返回200(或者返回204,表示回去的body中莫带有其他内容)。如果应用PUT请求创建资源,成功返回的HTTP状态码是201。响应的body是可选的——如果提供的言辞将会晤损耗又多之牵动富。在创建资源时不曾必要通过头部的岗位返回链接,因为客户端已设置了资源ID。请参见下的回到值部分。

  PUT不是一个康宁的操作,因为它们会修改(或创造)服务器上的状态,但她是幂等的。换句话说,如果你使用PUT创建或者更新资源,然后又调用,资源还是存在而状态不见面发生变化。

  例如,如果以资源增量计数器中调用PUT,那么这个调用方法就不再是幂等的。这种气象有时候会起,且可能可以证明它是未幂等性的。不过,建议维持PUT请求的幂等性。并强烈建议非幂等性的乞求使用POST。

POST

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

  例如:

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

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

  POST请求既非是平安之以未是幂等的,因此其给定义也非幂等性资源要。使用简单单相同的POST请求很可能会见招创建两只饱含相同信息的资源。

PUT和POST的创导于

  总之,我们建议利用POST来创造资源。当由客户端来决定新资源有着哪些URI(通过资源名称或ID)时,使用PUT:即如果客户端知道URI(或资源ID)是呀,则指向拖欠URI使用PUT请求。否则,当由服务器或服务端来决定创造的资源的URI时则利用POST请求。换句话说,当客户端在创造之前不晓得(或无法掌握)结果的URI时,使用POST请求来创造新的资源。

DELETE

  DELETE很易理解。它给用来因URI标识删除资源。

  例如:

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

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

  根据HTTP规范,DELETE操作是幂等的。如果您针对一个资源开展DELETE操作,资源就让移除了。在资源及屡次调用DELETE最终导致的结果尚且无异:即资源让移除了。但倘若拿DELETE的操作用于计数器(资源间),则DETELE将不再是幂等的。如前所陈述,只要数据尚未叫更新,统计以及测量的用法依然只是叫认为是幂等的。建议非幂等性的资源要使用POST操作。

  然而,这里出一个关于DELETE幂等性的警告。在一个资源达成第二破调整用DELETE往往会回到404(未找到),因为拖欠资源已经于移除了,所以寻找不顶了。这令DELETE操作不再是幂等的。如果资源是自从数据库被删除而休是吃概括地记为除去,这种情况用适宜让步。

  下表总结发生了关键HTTP的法以及资源URI,以及引进的返回值:

HTTP请求

/customers

/customers/{id}

GET

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

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

PUT

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

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

POST

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

404(未找到)

DELETE

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

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

 

资源命名

  除了当地运用HTTP动词,在创立一个方可知晓的、易于使的Web服务API时,资源命名可以说凡是无比具有争议与极重点的定义。一个吓的资源命名,它所对应之API看起还直观并且爱使。相反,如果命名不好,同样的API会给人倍感异常笨而难以知晓以及使用。当您待吗你的新API创建资源URL时,这里产生有有点技巧值得借鉴。

  从精神上说道,一个RESTFul
API最终还足以被略去地作为是同堆放URI的聚众,HTTP调用这些URI以及有用JSON和(或)XML表示的资源,它们中发出无数带有了互关联的链接。RESTful的而寻址能力要靠URI。每个资源且有温馨的地点或URI——服务器会提供的各国一个实惠的信还好视作资源来明。统一接口的法有地经URI和HTTP动词的结缘来化解,并可利用正规和约定。

  以控制你系统受到设使用的资源时,使用名词来定名这些资源,而非是用动词或动作来定名。换句话说,一个RESTful
URI应该干到一个有血有肉的资源,而休是干到一个动作。另外,名词还怀有局部动词没有底习性,这也是其他一个显然的要素。

  一些资源的例子:

  • 系的用户
  • 学员注册之学科
  • 一个用户帖子的时光轴
  • 关注其他用户的用户
  • 相同首关于骑马的稿子

  服务套件中之每个资源最少发生一个URI来标识。如果这URI能表示必定之义并且能充分描述她所表示的资源,那么它们便是一个极好的命名。URI应该有可预测性和分层结构,这将推进增强其的可理解性和可用性的:可预测指的是资源应该和名称保持一致;而分指的是数据具有涉达成的组织。这并非REST规则或专业,但是它们加重了对API的定义。

  RESTful
API是供被消费端的。URI的称和结构应当用她所抒发的意思传达给消费者。通常我们死不便知晓数码的鄂是啊,但是于您的数及而应该十分有或失掉尝试找到要回来给客户端的数码是呀。API是为客户端而计划之,而休是吗卿的多寡。

  假设我们本要是描述一个囊括客户、订单,列表项,产品相当职能的订单系统。考虑一下我们该如何来讲述在这服务遭遇所提到到之资源的URIs:

资源URI示例

  为了当系受插入(创建)一个新的用户,我们可以以:

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

 

  读取编号为33245之用户信息:

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

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

 

  下面是对活有关的URI的有的提议:

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

  用于创造新的制品。

 

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

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

 

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

  一种植方案是:

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

  这种方法可就此来创造订单,但缺少相应的用户数据。

  

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

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

  现在我们明白它是吗编号33245的用户创建一个订单。

 

  那下面是请返回的是什么吗?

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

  可能是一个号码也33245的用户所创建或者持有的订单列表。注意:我们得屏蔽对拖欠URI进行DELETE或PUT请求,因为其的操作对象是一个集。

 

  继续深入,那下面这个URI的求又象征什么为?

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

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

  从返回的这些章来拘禁,指定的资源或会见产生差不多个URIs,所以我们兴许吧待而提供这样一个URI
GET
http://www.example.com/orders/8769
,用来以未知晓用户ID的情状下基于订单ID来询问订单。

 

  更进一步:

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

  可能只是回去跟个订单中之第一单条款。

  现在你应当懂得什么是分开层结构了。它们并无是从严的规则,只是以保于您的劳务被这些强制的构造能重新爱给用户所知晓。与富有软件开发中之技巧一样,命名是成之要紧。

  

  多扣有些API的示范并学会控制这些技巧,和您的队友一起来完善而API资源的URIs。这里产生有APIs的例子:

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

资源命名的反例

  前面我们曾讨论了一些适度的资源命名的事例,然而有时有反面的例子吗够呛有教育意义。下面是有未极端有RESTful风格的资源URIs,看起比较乱。这些都是不对的例证! 

  首先,一些serivices往往使用单一的URI来指定服务接口,然后经过查询参数来指定HTTP请求的动作。例如,要创新编号12345的用户信息,带有JSON
body的伸手或是这么:

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

  尽管地方URL中之”services”的之节点是一个名词,但此URL不是起说的,因为对此持有的伸手而言,该URI的层级结构都是均等的。此外,它使GET作为HTTP动词来推行一个创新操作,这简直就是是相反人类(甚至是千钧一发的)。

  下面是另外一个创新用户之操作的事例:

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

  以及她的一个变种:

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

  你会经常见到于其它开发者的劳动套件中生成百上千这么的用法。可以观看,这些开发者试图去创造RESTful的资源名称,而且都起矣有些上扬。但是若依然能分辨出URL中的动词短语。注意,在此URL中我们无需要”update”这个词,因为咱们可借助HTTP动词来形成操作。下面这个URL正好说明了当时或多或少:

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

  这个请又是PUT和”update”,这会指向消费者出迷惑!这里的”update”指的凡一个资源也?因此,这里我们费些口舌也是期而会明白……

复数

  让咱来讨论一下复数和“单数”的争议…还没听说过?但这种争议确实有,事实上它好综合为这题目……

  在你的层级结构中URI节点是否要让取名也单数或复数形式也?举个例,你用来索用户资源的URI的命名是否用像下这样:

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

  或者:

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

  两栽办法还未曾问题,但普通我们都见面选择使用复数命名,以使得你的API
URI在有着的HTTP方法吃保持一致。原因是因这样同样种考虑:customers是劳务套件中之一个集结,而ID33245的这个用户则是此集中之里边一个。

  按照这个规则,一个采用复数形式的差不多节点的URI会是这么(注意粗体部分):

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

  “customers”、“orders”以及“lineitems”这些URI节点都以的凡复数形式。

  这表示你的每个根资源只需要少单主导的URL就好了,一个用以创造集合内的资源,另一个就此来冲标识符获取、更新和去资源。例如,以customers为例,创建资源得以行使下的URL进行操作:

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

  而读取、更新与去资源,使用下的URL操作:

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

  正使前方提到的,给一定的资源或发生多只URI,但当一个无比小的圆的增删改查功能,利用有限个简单的URI来拍卖就足够了。

  或许你会问:是否在有点情况下复数没有意义?嗯,事实上是如此的。当没有汇概念的时(此时复数没有意义)。换句话说,当资源就来一个之状况下,使用单数资源名称为是可的——即一个纯净的资源。例如,如果发生一个十足的完好安排资源,你可行使一个单数名称来表示:

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

  注意这里少configuration的ID以及HTTP动词POST的用法。假设每个用户有一个配备来说,那么这URL会是这般:

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

  同令人瞩目这里没有点名configuration的ID,以及从未让定POST动词的用法。在及时片个例中,可能啊会见有人觉得用POST是行之。好吧…

 

回表征

  正使前提到的,RESTful接口支持多资源特色,包括JSON和XML,以及让卷入的JSON和XML。建议JSON作为默认表征,不过服务端应该允许客户端指定其他表征。

  对于客户端请求的特性格式,我们可以于Accept头通过文件扩展名来进展点名,也得以经query-string等其它措施来指定。理想状态下,服务端可以支持所有这些方法。但是,现在正规更赞成被经过类似于文件扩展名的措施来进展点名。因此,建议服务端至少要支持以文件扩展名的不二法门,例如“.json”,“.xml”以及它们的包装版本“.wjon”,“.wxml”。

  通过这种办法,在URI中指定返回表征的格式,可以增进URL的可见性。例如,GET
http://www.example.com/customers.xml
将回到customer列表的XML格式的特色。同样,GET
http://www.example.com/customers.json
用回来一个JSON格式的性状。这样,即使是以无比基础之客户端(例如“curl”),服务使起来呢会见越加便利。推荐使用这种方法。

  此外,当url中尚无含格式说明时,服务端应该归默认格式的性状(假设为JSON)。例如:

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

  GET http://www.example.com/customers/12345.json

  以上两者返回的ID为12345底customer数据均为JSON格式,这是劳动端的默认格式。

  GET http://www.example.com/customers/12345.xml

  如果服务端支持的话,以上要返回的ID为12345之customer数据为XML格式。如果该服务器不支持XML格式的资源,将回到一个HTTP
404的缪。

  使用HTTP
Accept头被广泛认为是同种植更优雅的法子,并且可HTTP的正儿八经及意义,客户端可经这种措施来告诉HTTP服务端它们可支持的数据类型有哪些。但是,为了采取Accept头,服务端要又支持封装和未封装的应,你得兑现自定义的色——因为这些格式不是正经的类。这大大增加了客户端与服务端的繁杂。请参见RFC
2616底14.1节关于Accept头的详细信息(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1)。使用文件扩展名来指定数量格式是极致简单易行直接的方法,用最少之字符就足以好,并且支持脚本操作——无需采用HTTP头。

  通常当我们提到REST服务,跟XML是毫不相关的。即使服务端支持XML,也几从不丁提议在REST中使用XML。XML的业内及公约在REST中莫极端适用。特别是它并命名空间还没有,就还非该于RESTful服务体系中运用了。这才见面如业务变得更扑朔迷离。所以回来的XML看起再如JSON,它大概好读,没有模式及命名空间的界定,换句话来说是无论正式的,易于解析。

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

  REST指导原则有(根据统一接口规范)是application的状态通过hypertext(超文本)来导。这即是咱们平常所说之Hypertext
As The Engine of Application State
(即HATEOAS,用超文本来当应用程序状态机),我们在“REST是什么”相同节约中呢论及过。

  根据Roy
Fielding在外的博客中之叙述(http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertextdriven),REST接口中极其要之有的是超文本的使。此外,他还指出,在吃有其它有关的音讯之前,一个API应该是可用和而明白的。也就是说,一个API应当可以通过其链接导航及数的次第组成部分。不建议单独回去纯数据。

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

  另一方面,简单粗暴地拿一切链接集合返回会大大影响网络带来富。在实质上情形被,根据所待的准还是采取状态,API接口的通信量要基于服务器响应中超文本链接所涵盖的“摘要”数量来抵消。

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

  超链接太小化的做法是于极其酷限度地抽客户端和服务器之间的耦合的又,提高劳务端的可用性、可操纵性和可理解性。这些最小化建议是:通过POST创建资源并自GET请求返回集合,对于发出分页的事态后我们会干。

尽小化链接推荐

  在create的用例中,新建资源的URI(链接)应该以Location响应头中归,且应中心是拖欠的——或者仅包含新建资源的ID。

  对于自服务端返回的特性集合,每个表征应该当它们的链接集合中携带一个无比小的“自身”链接属性。为了方便分页操作,其它的链接可以在一个独自的链接集合中回到,必要常常得以分包“第一页”、“上同页”、“下同样页”、“最后一页”等消息。

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

链接格式

  参照整个链接格式的规范,建议遵守一些类似Atom、AtomPub或Xlink的风格。JSON-LD也没错,但并无于广泛采用(如果既让用过)。目前业内最常见的方式是使用含”rel”元素和含资源总体URI的”href”元素的Atom链接格式,不带有其他身份验证或询问字符串参数。”rel”元素得以蕴涵标准值”alternate”、”related”、”self”、”enclosure”和”via”,还有分页链接的“第一页”、“上平等页”、“下一样页”,“最后一页”。在待常得由定义并丰富应用她。

  一些XML
Atom格式的定义对用JSON格式表示的链接来说是低效的。例如,METHOD属性对于一个RESTful资源来说是勿待之,因为对于一个加以的资源,在享有支持之HTTP方法(CRUD行为)中,资源的URI都是相同之——所以单独列有这些是没必要的。

  让咱选一些有血有肉的例证来更是求证这或多或少。下面是调用创建新资源的乞求后底应:

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

  下面是响应头集合中隐含创建新资源的URI的Location部分:

HTTP/1.1 201 CREATED 
Status: 201 
Connection: close 
Content-Type: application/json; charset=utf-8 
Location: http://api.example.com/users/12346

  返回的body可以为空,或者隐含一个给包的应(见下文封装响应)。

  下面的事例通过GET请求获取一个非分包分页的特性集合的JSON响应:

{
  "data": [
    {
      "user_id": "42",
      "name": "Bob",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/42"
        }
      ]
    },
    {
      "user_id": "22",
      "name": "Frank",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/22"
        }
      ]
    },
    {
      "user_id": "125",
      "name": "Sally",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/125"
        }
      ]
    }
  ]
}

  注意,links数组中之各一样码都蕴含一个对“自身(self)”的链接。该数组还可能还蕴含其他关系,如children、parent等。

  最后一个例子是经GET请求获取一个含有分页的风味集合的JSON响应(每页显示3起),我们为起第三页的多寡:

{
  "data": [
    {
      "user_id": "42",
      "name": "Bob",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/42"
        }
      ]
    },
    {
      "user_id": "22",
      "name": "Frank",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/22"
        }
      ]
    },
    {
      "user_id": "125",
      "name": "Sally",
      "links": [
        {
          "rel": "self",
          "href": "http://api.example.com/users/125"
        }
      ]
    }
  ],
  "links": [
    {
      "rel": "first",
      "href": "http://api.example.com/users?offset=0&limit=3"
    },
    {
      "rel": "last",
      "href": "http://api.example.com/users?offset=55&limit=3"
    },
    {
      "rel": "previous",
      "href": "http://api.example.com/users?offset=3&limit=3"
    },
    {
      "rel": "next",
      "href": "http://api.example.com/users?offset=9&limit=3"
    }
  ]
}

  在这事例中,响应中用于分页的links集合中之各级一样项都饱含一个对“自身(self)”的链接。这里可能还会见时有发生局部干到集的外链接,但还同分页本身无关。简而言之,这里来个别独地方含有links。一个虽是data对象中所包含的汇(这个呢是接口要回来给客户端的多少表征集合),其中的诸一样宗至少要包括一个针对性“自身(self)”的links集合;另一个虽然是一个独门的靶子links,其中包括与分页相关的链接,该片段的始末适用于全体集合。

  对于经过POST请求创建资源的状态,需要在应头着含一个关系新建对象链接的Location

包响应

   服务器可以于应中又返回HTTP状态码和body。有无数JavaScript框架没有拿HTTP状态响应码返回给最终的开发者,这频繁会导致客户端无法根据状态码来确定具体的作为。此外,虽然HTTP规范着起充分多种响应码,但是往往只发少数客户端会关切这些——通常大家就于乎”success”、”error”或”failture”。因此,将应内容跟应状态码封装在蕴藏响应信息的特征着,是发出必不可少之。

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

  这些提案在实践中并无了含所有的情事。基本上,现在太好之做法是据以下属性封装常规(非JSONP)响应:

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

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

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

  返回error的包装响应:

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

  这简单个包响应对应之XML如下:

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

  和:

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

拍卖跨域问题

   我们还听说了有关浏览器的同源策略要同源性需求。它凭借的凡浏览器只能请时方显示的站点的资源。例如,如果手上着显示的站点是www.Example1.com,则该站点不能够针对www.Example.com倡议呼吁。显然这会影响站点访问服务器的方法。

  时产生星星点点只给大规模接受的支持跨域请求的法:JSONP和跨域资源共享(CORS)。JSONP或“填充的JSON”是同种下模式,它提供了一个主意要来自不同域中之服务器的数码。其行事措施是起服务器返回任意的JavaScript代码,而休是JSON。客户端的应由JavaScript解析器进行剖析,而不是直接解析JSON数据。另外,CORS是同等种web浏览器的技巧标准,它吧web服务器定义了一如既往种植办法,从而允许服务器的资源可以吃免同域的网页访问。CORS被当是JSONP的新式替代品,并且可给所有现代浏览器支持。因此,不建议使用JSONP。任何情况下,推荐选择CORS。

支持CORS

  于服务端实现CORS很粗略,只待以殡葬响应时顺便HTTP头,例如: 

Access-Control-Allow-Origin: *

  只有当数是国有使用的情状下才会用造访来源设置为”*”。大多数景象下,Access-Control-Allow-Origin头应该指定哪些域可倡导一个CORS请求。只有用跨域访问的URL才装CORS头。

Access-Control-Allow-Origin: http://example.com:8080
http://foo.example.com

  以上Access-Control-Allow-Origin头中,被装为单独允许给信赖的地带可以看。

Access-Control-Allow-Credentials: true

  只当需要时才用方面这header,因为若用户已报到的话,它会同时发送cookies/sessions。

  这些headers可以通过web服务器、代理来进展布局,或者由服务器本身发送。不推荐在服务端实现,因为大无灵敏。或者,可以运用方面的第二种办法,在web服务器上部署一个用空格分隔的地区的列表。更多关于CORS的始末可参考这里:http://enable-cors.org/。

支持JSONP

  JSONP通过采用GET请求避开浏览器的界定,从而实现对拥有服务的调用。其行事原理是央求方在呼吁的URL上上加一个字符串查询参数(例如:jsonp=”jsonp_callback”),其中“jsonp”参数的值是JavaScript函数称呼,该函数在闹应返回时拿会给调用。

  由于GET请求中没有包含呼吁求体,JSONP在行使时有着严重的局限性,因此数据必须透过字符串查询参数来传递。同样的,为了支持PUT,POST和DELETE方法,HTTP方法必须也由此字符串查询参数来传递,类似_method=POST这种形式。像这样的HTTP方法传送方式是勿引进应用的,这会为服务处于安全风险中。

  JSONP通常以有些非支持CORS的老旧浏览器被行使,如果要是转移成为支持CORS的,会潜移默化整个服务器的架。或者我们也可由此代办来实现JSONP。总之,JSONP正在让CORS所替代,我们理应尽可能地以CORS。

  为了在服务端支持JSONP,在JSONP字符串查询参数传递时,响应必须要实行以下这些操作:

  1. 响应体必须封装成一个参数传递给jsonp中指定的JavaScript函数(例如:jsonp_callback(“<JSON
    response body>”))。
  2. 始终返回HTTP状态码200(OK),并且用真实的状态作为JSON响应中的同样有归。

  另外,响应体中经常要含有响应头。这叫JSONP回调方法要依据响应体来规定响应处理方式,因为其自己无法获悉真实的响应头和状态值。

  下面的例证是比照上述办法封装的一个回去error状态的jsonp(注意:HTTP的应状态是200):

jsonp_callback("{'code':'404', 'status':'error','headers':[],'message':'resource XYZ not
found','data':'NotFoundException'}")

  成功创办后底应类似于如此(HTTP的响应状态仍是200):

jsonp_callback("{'code':'201', 'status':'error','headers':
[{'Location':'http://www.example.com/customers/12345'}],'data':'12345'}")

 

查询,过滤与分页

  对于大数据集,从带宽的角度来拘禁,限制返回的数据量是不行关键之。而起UI处理的角度来拘禁,限制数据量也一样关键,因为UI通常只能展现大数量集中的同样有点有数据。在数据集的增长速度不确定的状下,限制默认返回的数据量是大有必要的。以Twitter为例,要取有用户的推文(通过个人主页的年月轴),如果没有专门指定,请求默认只见面回去20长记下,尽管系统最多可回到200修记下。

  除了限制返回的数据量,我们还得考虑怎么对运据集进行“分页”或下拉滚动操作。创建数量的“页码”,返回大数目列表的就解片段,然后标出数据的“前一样页”和“后同样页”——这无异行给称为分页。此外,我们也许吧待指定响应中将包含如何字段或性质,从而限制返回值的数码,并且我们愿意最后会由此一定值来开展查询操作,并针对性回到值进行排序。

  有点儿种关键的法来以限制查询结果和履分页操作。首先,我们得以建立一个目录方案,它好以页码为导向(请求被使被起各个一样页的记录数及页码),或者以记录也导向(请求被直接吃起第一长条记下及结尾一长记下)来确定返回值的开场位置。举个例子,这点儿种植艺术分别表示:“给闹第五页(假设每页有20长达记下)的笔录”,或“给出第100到第120长之记录”。

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

  下文将介绍一种植方式,既能支持Dojo这样的分页模式(在伸手求头中为来记录之限制),也能够支持使用字符串查询参数。这样一来服务端将易得愈灵敏,既可以使用类似Dojo一样先进的UI工具集,也足以采用简单直接的链接和标签,而无需另行为这个增加复杂的开工作。但如服务不直支持UI功能,可以设想不要当请求头中为起记录范围。

  要专门指出的凡,我们连无引进以有着服务中使查询、过滤和分页操作。并无是独具资源且默认支持这些操作,只有少数特定的资源才支撑。服务以及资源的文档应当说明如何接口支持这些纷繁的作用。

结果限制

  “给闹第3暨第55条的记录”,这种求数据的道和HTTP的字节范围规范更平等,因此我们得以就此它们来标识Range
header。而“从第2条记下开始,给有无限多20长达记下”这种方式重新爱阅读与晓,因此我们普通会用字符串查询参数的法来表示。

  综上所述,推荐既支持用HTTP Range
header,也支持下字符串查询参数——offset(偏移量)和limit(限制),然后以服务端对响应结果进行限制。注意,如果又支持即半栽方式,那么字符串查询参数的优先级要超越Range
header。

  这里你或许会见来个问题:“这有限种植方式效果相似,但是返的数额未完全一致。这会不见面给人口歪曲呢?”恩…就是少单问题。首先使回的凡,这的确会为丁歪曲。关键是,字符串查询参数看起越清晰易懂,在构建与剖析时更便民。而Range
header则再多是出于机械来行使(偏向于底层),它更加符合HTTP使用正规。

  总之,解析Range
header的行事会多复杂度,相应的客户端在构建请求时为急需展开有处理。而使用单独的limit和offset参数会愈便于了解和构建,并且不欲针对开发人员有再度多之求。

于是范围标记进行限定

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

  Range: items=0-24

  注意记录是从0开始之连接字段,HTTP规范着证明了怎样运用Range
header来请求字节。也就是说,如果假定乞求数据汇总之率先长条记下,范围应该从0开始算打。上述的恳求将会晤回到前25个记录,假要数据汇总至少有25条记下。

  而以服务端,通过检查请求的Range
header来确定拖欠归哪些记录。只要Range
header存在,就会出一个简练的正则表达式(如”items=(\d+)-(\d+)”)对该展开分析,来获得要找的范围值。

据此字符串查询参数进行界定

  字符串查询参数为当做Range
header的替代选择,它应用offset和limit作为参数名,其中offset代表要询问的第一长记下编号(与上述的用来范围标记的items第一独数字同样),limit代表记录的极度老条数。下面的例证返回的结果和上述用范围标记的例证一样:

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

  Offset参数的价值与Range
header中的切近,也是从0开始算计。Limit参数的价是返回记录的极特别数额。当字符串查询参数中莫指定limit时,服务端应当于起一个不够省之太可怜limit值,不过这些参数的施用还需要在文档中开展认证。

依据范围之响应

  对一个基于范围之乞求来说,无论是通过HTTP的Range
header还是经过字符串查询参数,服务端都应该有一个Content-Range
header来响应,以表明返回记录的条数和总记录数:

  Content-Range: items 0-24/66

  注意这里的终究记录数(如本例中之66)不是从0开始计的。如果假定请求数据集中之尾声几条记下,Content-Range
header的内容应是这么:

  Content-Range: items 40-65/66

  根据HTTP的正统,如果响应时总记录数未知或难计算,也可以用星号(”*”)来替代(如本例中的66)。本例中响应头也可这样形容:

  *Content-Range: items 40-65/**

  不过只要专注,Dojo或有另的UI工具或不支持该符号。

分页

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

  Range: items=25-49

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

  GET …?offset=25&limit=25

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

  Content-Range: 25-49/66

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

  按日期排列的数据集(例如Twitter
feed)就是同样种植普遍的景象。虽然您还是得以对数码进行分页,但奇迹用”after”或”before”这样的根本字连和Range
header(或者跟字符串查询参数offset和limit)配合来贯彻分页,看起会更简明易亮。

  例如,要取给定时间穿的眼前20漫长评论:

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

  Range: items=0-19

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

*  Range: items=0-19*

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

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

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

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

  如果请时没点名要返回的数据范围,服务端返回了平等组默认数据要限制的最充分数据集,那么服务端同时也应当于回结果被富含Content-Range
header来和客户端进行确认。以点个人主页的时刻轴为条例,无论客户端是不是指定了Range
header,服务端每次都单回20长记下。此时,服务端响应的Content-Range
header应该包含如下内容:

  Content-Range: 0-19/4125

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

结果的过滤和排序

  针对返回结果,还待考虑什么当服务端对数码进行过滤跟排,以及哪些按照指定的依次对子数据进行搜。这些操作可以同分页、结果限制,以及字符串查询参数filter和sort等互相结合,可以兑现强的数据检索功能。

  再强调平等糟糕,过滤和排序都是繁体的操作,不待默认提供给有的资源。下文将介绍如何资源需要提供过滤与排序。

过滤

  以本文中,过滤被定义也“通过一定的格来规定要要赶回的数量,从而减少返回的数”。如果服务端支持一模仿完整的比运算符和错综复杂的基准相当,过滤操作以变得相当复杂。不过我们日常会动用部分略的表达式,如starts-with(以…开始)或contains(包含)来进行匹配,以管返回数据的完整性。

  在咱们开始谈论过滤的字符串查询参数之前,必须先了解怎么而运单个参数而无是大抵独字符串查询参数。从根本上来说是为着削减参数名称的冲突。我们曾起offsetlimitsort(见下文)参数了。如果可能的言辞还会发出jsonpformat标识符,或许还见面生出afterbefore参数,这些都是于本文遭受关系了之字符串查询参数。字符串查询中利用的参数越多,就更为可能致参数名称的冲突,而下单个过滤参数则会将闯的可能性降低到最低。

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

  通过引入一组广泛的、公认的分隔符,用于过滤的表达式可以坐好直观的形式被用。用这些分隔符来设置过滤查询参数的价值,这些分隔符所创建的参数名/值对能越来越爱地为服务端解析并提高多少查询的特性。目前曾经部分分隔符包括用来分隔每个过滤短语的竖线(”|”)和用来分隔参数名和价值的对仗冒号(”::”)。这套分隔符足够唯一,并符合大多数情,同时用它们来构建的字符串查询参数为越发爱了解。下面将就此一个粗略的事例来介绍她的用法。假设我们想只要受名也“Todd”的用户们发送请求,他们住在丹佛,有着“Grand
Poobah”之称。用字符串查询参数实现之呼吁URI如下:

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

  双冒号(”::”)分隔符将属于性名和价值分开,这样属性值就可知包含空格——服务端能再易于地起属于性值中剖析出分隔符。

  注意查询参数名/值对着之习性名要和服务端返回的习性名相匹配。

  简单而行。有关大小写敏感的题材,要根据具体情况来拘禁,但总的看,在毫不关心大小写的场面下,过滤效果可以死好地运转。若查询参数名/值对吃的属于性值未知,你为可据此星号(”*”)来代替。

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

排序

  排序决定了由服务端返回的笔录之一一。也尽管是针对性响应中的大半漫漫记下进行排序。

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

  举个例证,如果我们怀念按部就班用户之姓氏和叫展开升序排序,而对雇佣时间开展降序排序,请求将是这么的:

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

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

 

服务版本管理

   坦率地谈,一说到本就会见受人以为大困难,很辛苦,不顶爱,甚至会叫人口看难受——因为及时会追加API的复杂度,并以可能会见指向客户端有一些影响。因此,在API的宏图受到如尽量避免多只不等之本子。

  不支持版本,不以版本控制作为糟糕的API设计之仗。如果您以APIs的宏图受到引入版本,这迟早还见面于您捉狂。由于返回的多寡通过JSON来展现,客户端会由于不同之版要收到不同的性质。这样即便会见在有的题目,如自内容己以及说明规则方面改变了一个曾存在的性能的意义。

  当然,我们无能为力避免API可能以少数时段用改变返回数据的格式和情节,而立吗拿导致消费端的有的转,我们该避免进行一些第一的调动。将API进行版本化管理是避免这种重大转变之平等种中措施。

由此内容商支持版本管理

  以往,版本管理通过URI本身的版号来形成,客户端在恳求的URI中标明要获得之资源的版本号。事实上,许多良商家要Twitter、Yammer、Facebook、Google等时以她们之URI里使用版本号。甚至像WSO2这样的API管理工具也会见于她的URLs中求版本号。

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

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

  例如,要收获一个user的JSON格式的数码:

  #Request:

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

  #Response:

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

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

  现在,我们本着同一资源要版本2底多寡:

  #Request:

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

  #Response:

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

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

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

  由于Accept
header可以被装为允许多媒体类型,在应请求时,服务器将把响应的Content-Type
header设置为最般配配客户端请求内容之路。更多信息可以参见http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.Html

  例如:

  #Request

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

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

  上述呼吁中,假设服务器支持JSON
和XML格式的伸手,或者个别种都支持,那么将出于服务器来控制最终回哪种类型的数据。但无服务器选择哪一样栽,都见面在响应中含Content-Type
header。

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

  #Response

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

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

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

  #Request

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

  {“name”:”Marco Polo”}

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

  #Request

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

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

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

  并不需要在列一个要中都指定版本号。由于HTTP
content-negotiation(内容商)遵循类型的“最佳匹配”方式,所以若的API也应该按照这一点。根据当时同样原则,当客户端从未点名版本时,API应当返回所支撑之无比早版本。

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

  #Request

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

  #Response

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

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

  相应地,当为POST方式向服务器发送数据常常,如果服务器支持多个例外版本,而求时同时尚未点名版本,和点的例子一样——服务器会将无限小/最早版本的数据包含在body中。为了进行验证,下面的例子以JSON格式请求一个含有多本资源的服务器,来创造一个新用户(预期会返回版本1):

  #Request

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

  {“name”:”Marco Polo”}

  #Response

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

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

要不支持的本子

  当呼吁一个不支持的本子号时(包含在API生命周期中曾经熄灭的资源版本),API应当返回一个左的HTTP状态码406(表示未吃纳)。此外,API还应当返回一个饱含Content-Type:
application/json的响应体,其中饱含一个JSON数组,用于证明该服务器支持之路。

  #Request

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

  #Response

  HTTP/1.1 406 NOT ACCEPTABLE 

  Content-Type: application/json

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

咦时候该创建一个初本子?

  API开发中之不在少数点都见面打破约定,并最后对客户端有一些不良影响。如果您无确定API的改动会带哪些的名堂,保险起见最好考虑采用本控制。当你当设想提供一个初本子是否适用时,或者考虑针对现有的返表征进行改动是否必然能满足急需并给客户端所承受时,有诸如此类几个元素如考虑。

破坏性的改动

  • 变更属性名(例如将”name”改成为”firstName”)
  • 除去属性
  • 改属性的数据类型(例如将numeric变为string,
    boolean变为bit/numeric,string 变为 datetime等等)
  • 反验证规则
  • 于Atom样式的链接中,修改”rel”的价值
  • 以现有的工作流中引入必要资源
  • 转移资源的定义/意图;概念/意图或资源状态的义不同为其原本的意思。例如:
    • 一个content
      type是text/html的资源,之前表示的是富有支持的媒体类型的一个”links”集合,而初的text/html则意味着的凡用户输入的“web浏览器表单”。
    • 一个富含”endTime”参数的API,对资源”…/users/{id}/exams/{id}”表达的义是生当大时间付诸试卷,而新的含义则是考查的约定完毕时间。
  • 透过长新的字段来改变现有的资源。将点滴个资源集合为一个并弃用旧的资源。
    • 来这样少单资源”…/users/{id}/dropboxBaskets/{id}/messages/{id}”和”…/users/{id}/dropboxBaskets/{id}/messages/{id}/readStatus”。新需要是拿readStatus资源的性能放到单独的message资源遭到,并弃用readStatus资源。这将招致messages资源被指向readStatus资源的链接给移除。

  虽然上面列有的连无完美,但其给起了一部分会晤指向客户端有破坏性影响的变迁类型,这时需要考虑提供一个初资源还是新本子。

非破坏性的改

  • 在返的JSON中补充加新属性
  • 累加指向任何资源的”link”
  • 添加content-type支持的新格式
  • 添加content-language支持之初格式
  • 由于API的创建者和顾客都要处理不同之casing,因此casing的转变无关紧要

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

  建议针对性单个的资源拓展版本控制。对API的有些变更,如修改工作流,也许如果跨越多单资源的版本控制,以之来严防对客户端起破坏性的影响。

使Content-Location来加强响应

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

带有Content-Type的链接

  Atom风格的链接支持”type”属性。提供足够的音信以便客户端好对一定的本子与情节类型进行调用。

觅来支持之版

自我应该而且支持小只本子?

  维护多个不等之版会受工作转移得烦、复杂、容易失误,而且代价高,对于其他给定的资源,你应当支持不越2个版。

弃用

  Deprecated(弃用)的目的是故来验证资源对API仍然可用,但于前见面无在并转移得不可用。瞩目:弃用的时长将由弃用政策决定——这里并没为起概念。

自我哪些告客户端给弃用的资源?

  许多客户端将来拜会的资源或于新本子引入后会见让废弃掉,因此,他们得出一致种植方式来发现及监察他们的应用程序对委用资源的采用。当呼吁一个弃用资源时,API应该健康应,并蕴含一个布尔项目的自定义Header
“Deprecated”。以下用一个事例来拓展说明。

  #Request

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

  #Response

  HTTP/1.1 200 OK
  Content-Type: application/json; version=1
  Deprecated: true
  {“id”:”12345”, “name”:”Joe DiMaggio”}

 

日子/时间拍卖

  如果没妥善地、一致地处理好日期及时空来说,这将改为一个大累。我们经常会面遇上时区的题目,而且由于日期在JSON中是以字符串的格式在的,如果无指定统一之格式,那么解析日期也会见是一个问题。

  于接口内部,服务端应该为UTC或GMT时间来存储、处理及缓存时间戳。这将使得化解日期与时间之题目。

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

  有一个大概的法子好缓解这些问题——在字符串中总用同一之格式,包括时间片(带有时区信息)。ISO8601时间格式是一个是的缓解方案,它采用了一心增强的时光格式,包括小时、分钟、秒和秒的小数部分(例如yyyy-MM-dd’T’HH:mm:ss.SSS’Z’)。建议在REST服务之body内容遭(请求和响应均包括)使用ISO8601代表享有的日子格式。

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

  对于那些创建基于浏览器的用户界面来说,ECMAScript5正式一开始就是富含了JavaScript解析及创造ISO8601日期的情,所以其应有成为我们所说之主流浏览器所遵循的措施。当然,如果你要是支持那些不能自动解析日期的旧版浏览器,可以下JavaStript库或正则表达式。这里出几个可分析及创ISO8601时间的JavaStript库:

  http://momentjs.com/

  http://www.datejs.com/

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

  然而上述提议才适用于HTTP请求或响应内容遭的JSON和XML内容,HTTP规范对HTTP
headers使用另外一样栽不同的格式。在被RFC1123还给之RFC822中指出,该格式包括了各种日期、时间与date-time格式。不过,建议始终以时戳格式,在你的request
headers中它看起像这么:

  Sun, 06 Nov 1994 08:49:37 GMT

  不过,这种格式没有考虑毫秒或者秒的十进制小数。Java的SimpleDataFormat的格式串是:”EEE,
dd MMM yyyy HH:mm:ss ‘GMT'”。

 

保护服务之安康

  Authentication(身份验证)指的凡肯定给定的呼吁是起服务都掌握的某(或某个系统)发出之,且请求者是外自己所声明的异常人。Authentication是为印证请求者的真实身份,而authorization(授权)是为着说明请求者有权力去执行于请的操作。

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

  1. 客户端发起一个要,将authentication的token(身份验证令牌)包含在X-Authentication
    header中,或者将token叠加以恳求的查询串参数中。
  2. 服务器对authorization
    token(授权令牌)进行反省,并展开求证(有效还无过),并冲令牌内容分析或者加载认证中心。
  3. 服务器调用授权服务,提供证明中心、被呼吁资源与必备之操作许可。
  4. 若授权通过了,服务器将会见连续健康运转。

  上面第三步的开支可能会见比深,但是要是如果在一个不过缓存的权能决定列表(ACL),那么在产生远程请求前,可以在地面创建一个授权客户端来缓存最新的ACLs。

身份验证

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

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

传安全

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

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

授权

  对服务的授权和对任何应用程序的授权一样,没有其他区别。它根据这样一个题目:“主体是否对准加的资源发要的许可?”这里给出了简易的老三件数据(主体,资源和许可),因此好爱构造一个支持这种概念的授权服务。其中核心是受予以资源访问许可的丁要体系。使用这些相似概念,就可以吗各个一个主题构建一个缓存访问控制列表(ALC)。

应用程序安全

  对RESTful服务以来,开发一个康宁之web应用适用同的标准。

  • 在服务器上证实所有输入。接受“已知道”的正确性的输入并拒绝错误的输入。
  • 防止SQL和NoSQL注入。
  • 采用library如微软的Anti-XSS或OWASP的AntiSammy来针对输出的数量开展编码。
  • 用消息的尺寸限制在规定的字段长度内。
  • 劳务应该只有显示一般的错误信息。
  • 设想工作逻辑攻击。例如,攻击者可过了多步骤的预购流程来预订产品如果不论是需输入信用卡信息呢?
  • 本着可疑的活动记录日志。

  RESTful安全需要专注的地方:

  • 说明数据的JSON和XML格式。
  • HTTP动词应该受限制于许的措施中。例如,GET请求不可知去一个实体。GET用来读取实体而DELETE用来删除实体。
  • 小心race
    conditions(竞争规则——由于个别只或基本上独过程竞争下无可知于以做客的资源,使得这些经过有或坐日子达到推的次第由要产出问题)。

  API网关可用于监视、限制与控制对API的走访。以下内容可由于网关或RESTful服务实现。

  • 监API的行使状况,并问询哪些活动是健康的,哪些是非正常的。
  • 限定API的使,使恶意用户不能够停少一个API服务(DOS攻击),并且产生能力阻止恶意之IP地址。
  • 拿API密钥存储在加密的安康密钥库公海赌船网站中。

 

缓存和可伸缩性

  通过以网层级消除通过远程调用来获取请求的多少,缓存提高了网的但扩展性。服务通过以应中安headers来提高缓存的力量。遗憾的凡,HTTP
1.0负与缓存相关的headers与HTTP
1.1差,因此服务器如果又支持有限种版本。下表给闹了GET请求而支持缓存所须的最好少headers集合,并于出了确切的讲述。

HTTP Header

描述

示例

Date

一呼百应返回的日子和岁月(RFC1123格式)。

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

Cache-Control

应可给缓存的极酷秒数(最酷age值)。如果响应不支持缓存,值为no-cache。

Cache-Control: 360

Cache-Control: no-cache

Expires

假若被有了最大age值,该日穿(RFC1123格式)表示的凡响应过期的时空,也便是Date(例如当前日子)加上最特别age值。如果响应不支持缓存,该headers不有。

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

Pragma

当Cache-Control为no-cache时,该header的价为深受设置为no-cahche。否则,不在。

Pragma: no-cache

Last-Modified

资源本身最后为修改的年华戳(RFC1123格式)。

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

  为了简化,这里选出一个应中的headers集合的例证。这是一个简的对资源进行GET请求的响应,缓存时长为同一天(24时):

  Cache-Control: 86400
  Date: Wed, 29 Feb 2012 23:01:10 GMT
  Last-Modified: Mon, 28 Feb 2011 13:10:14 GMT
  Expires: Thu, 01 Mar 2012 23:01:10 GMT

  下面是一个近似的例子,不过缓存被全然禁用:

  Cache-Control: no-cache
  Pragma: no-cache

ETag Header

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

  ETag: “686897696a7c876b7e”

 

HTTP状态码(前10)

  以下是由于RESTful服务或API返回的顶常用之HTTP状态码,以及一些关于她广泛用法的简易说明。其它HTTP状态码不极端经常使用,它们或者更新鲜,要么更尖端。大多数劳务套件只支持这些常用的状态码,甚至只有支持中的同一组成部分,并且它还能够正常干活。

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

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

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

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

  400 (BAD REQUEST)
—— 用于行要时或许滋生无效状态的相似错误代码。如域名无效错误、数据丢失等。

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

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

  404 (NOT FOUND)
—— 无论资源存不有,无论是否来401、403的限制,当呼吁的资源找不顶常,出于安全因素考虑,服务器都可以动用该错误码来掩盖。

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

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

 

叠加资源

书籍

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

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

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

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

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

网站

  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

相关文章