RESTful服务至上实践葡京网上娱乐场

诸如像德意志联邦共和国的BROOKLYN更加用来打理胡子的胡须梳 ▼

DELETE

  DELETE很简单精晓。它被用来依照URI标识删除资源。

  例如:

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

  当删除成功时,再次回到HTTP状态码200(表示正确),同时会顺手一个响应体body,body中或许含有了删除项的数目(那会占用部分互联网带宽),或者封装的响应(参见上面的重返值)。也得以再次来到HTTP状态码204(表示无内容)表示不曾响应体。不问可知,可以回来状态码204意味从未响应体,或者重临状态码200而且附带JSON风格的响应体。

  按照HTTP规范,DELETE操作是幂等的。假如您对一个资源拓展DELETE操作,资源就被移除了。在资源上反复调用DELETE最后致使的结果都同一:即资源被移除了。但只要将DELETE的操效能于计数器(资源内部),则DETELE将不再是幂等的。如前方所述,只要数据尚未被更新,统计和测量的用法照旧可被认为是幂等的。指出非幂等性的资源请求使用POST操作。

  然则,那里有一个有关DELETE幂等性的告诫。在一个资源上第二次调用DELETE往往会回到404(未找到),因为该资源已经被移除了,所以找不到了。那使得DELETE操作不再是幂等的。如若资源是从数据库中除去而不是被略去地标记为除去,那种景色须求得体让步。

  下表总括出了最主要HTTP的章程和资源URI,以及推荐的重临值:

HTTP请求

/customers

/customers/{id}

GET

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

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

PUT

404(未找到),除非你想在漫天集合中创新/替换每个资源。

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

POST

201(创造),带有链接到/customers/{id}的岗位头新闻,包涵新的ID。

404(未找到)

DELETE

404(未找到),除非您想删除所有集合——平时不被允许。

200(正确)。要是没有找到ID或ID无效则赶回404(未找到)。

 

如若大家有察觉什么好玩的牌子,可以在数短论长下分享给我们。

    支持JSONP

本人要好喜好如何,

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

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

「探个店」是 JJJB
在品味的一个新栏目。跟大家看看一些妙不可言的品牌清劲风趣的店。跟大家大快朵颐部分大家协作的成品的来路。

    过滤

在阿峰的别人圈子的微信群里常听到的有的话,和大家 JJJB
的微信群的用户狠差异。他们不时会说:

非破坏性的改动

  • 在回去的JSON中添加新属性
  • 添加指向任何资源的”link”
  • 添加content-type帮助的新格式
  • 添加content-language协助的新格式
  • 出于API的主创者和消费者都要处理分歧的casing,由此casing的转移毫无干系首要

那是我们 JJJB 自己做了狠久,都还不曾办好的一件事。

REST是什么

何况仍旧个买手店总总经理。

  联合接口

黄铜复刻的子弹型战壕打火机

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)
—— 当服务器抛出至极时,捕捉到的一般错误。

 

大家明日再见

资源命名的反例

  后边大家早已研究过部分适龄的资源命名的例子,然则有时一些反面的例证也很有教育意义。下边是有的不太具有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”指的是一个资源吗?由此,那里我们费些口舌也是意在您可知清楚……

穿什么样的衣服

HTTP状态码(前10)

传统意义上的阿美咔叽文化,或者大家普遍一点说,叫「美式复古」的学识。半数以上的着装和生存方式的尝尝是基层的。

带有Content-Type的链接

  Atom风格的链接匡助”type”属性。提供足够的音讯以便客户端可以对特定的版本和内容类型举办调用。

比较狠多牛仔复古品牌以来,Japan Blue
的做工精美,又相比吻合南亚人的版型。极舒适的布料和天罗地网的穿着,是足以常备的司空眼惯拔取▼

破坏性的改动

  • 变动属性名(例如将”name”改成”firstName”)
  • 删去属性
  • 变更属性的数据类型(例如将numeric变为string,
    boolean变为bit/numeric,string 变为 datetime等等)
  • 转移验证规则
  • 在Atom样式的链接中,修改”rel”的值
  • 在现有的工作流中引入要求资源
  • 改变资源的定义/意图;概念/意图或资源气象的含义分歧于它原有的意义。例如:
    • 一个content
      type是text/html的资源,以前表示的是颇具接济的媒体类型的一个”links”集合,而新的text/html则象征的是用户输入的“web浏览器表单”。
    • 一个富含”end提姆e”参数的API,对资源”…/users/{id}/exams/{id}”表达的含义是学员在越发时刻付诸试卷,而新的意义则是考试的预约达成时间。
  • 透过抬高新的字段来改变现有的资源。将多个资源集合为一个并弃用原始的资源。
    • 有那样五个资源”…/users/{id}/dropboxBaskets/{id}/messages/{id}”和”…/users/{id}/dropboxBaskets/{id}/messages/{id}/readStatus”。新须要是把readStatus资源的属性放到单独的message资源中,并弃用readStatus资源。那将招致messages资源中指向readStatus资源的链接被移除。

  就算上面列出的并不到家,但它交给了部分会对客户端爆发破坏性影响的变更类型,那时急需考虑提供一个新资源或新本子。

一旦有心的话,你可以翻翻自己在天猫买衣服的快递,看看有多少是从山东石家庄寄到了您手里。

传输安全

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

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

跟京城日本东京南京那多少个圈子里知名的买手店不同,阿峰的店实际上不算「潮」。他又结婚在四川菲尼克斯,一个南方非凡小的都会▼

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

绝不只把卖东西当作卖来看,

  传输安全

日本的多少个平民品牌,比如讲 Japan Blue,是阿峰店里的常客。

  PUT

把好东西分享给别人,然后找到跟自己审美和感兴趣几乎的一群人。那是何其大的一种乐趣▼

  复数

前几日的话题就先到那边

  按需编码(可选)

好几千块钱一台,大不列颠及北爱尔兰联合王国ANGLE POISE的台灯 ▼

身份验证

  方今最好的做法是应用OAuth身份验证。强烈推荐OAuth2,但是它依然居于草案情况。或者选取OAuth1,它完全可以胜任。在少数意况下也得以拔取3-Legged
OAuth。越来越多关于OAuth的标准可以查阅那里http://oauth.net/documentation/spec/

  OpenID是一个叠加选取。但是提议将OpenID作为一个增大的身份验证选项,以OAuth为主。更多关于OpenID的正式可以查阅那里http://openid.net/developers/specs/

追求简单又更好玩的生活方法,那在阿峰和她的旁人朋友圈子里,你会看出得越来越多一些。

链接格式

  参照整个链接格式的规范,指出遵从一些像样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

而是在找一个能照亮自己生活的地方。

日期/时间拍卖

  若是没有妥善地、一致地处理好日期和岁月的话,那将改为一个大麻烦。大家平时会碰着时区的难题,而且由于日期在JSON中是以字符串的格式存在的,即使未指定统一的格式,那么解析日期也会是一个难点。

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

从衣裳纺织产业的基地,到追求做出更好的东西更有味道东西,追求慢一点更小巧的生存方法,变成了赶来帕罗奥图那座小城的大千世界的部分变通

    我应当而且接济多少个本子?

但是你们看,假诺唯有「基本款」的话,生活的确是蛮乏味的。
每个人过的光阴都会狠像。穿的玩的吃的用的,看来看去都是大约的指南。我勒个次奥,

  成立适当粒度的资源

有段日子自己还特地留意过这几个玩具在阿峰店里的销量。就跟预想的同样,大致就是没有。

应用程序安全

  对RESTful服务来说,开发一个平安的web应用适用同样的规范。

  • 在服务器上印证所有输入。接受“已知”的不利的输入并拒绝错误的输入。
  • 防止SQL和NoSQL注入。
  • 动用library如微软的Anti-XSS或OWASP的Anti萨姆my来对出口的数量开展编码。
  • 将新闻的长短限制在规定的字段长度内。
  • 服务应该只突显一般的错误信息。
  • 设想工作逻辑攻击。例如,攻击者可以跳过多步骤的预购流程来预约产品而无需输入信用卡音讯呢?
  • 对猜忌的移动记录日志。

  RESTful安全须要留意的地点:

  • 注解数据的JSON和XML格式。
  • HTTP动词应该被限定在允许的措施中。例如,GET请求不能够去除一个实体。GET用来读取实体而DELETE用来删除实体。
  • 注意race
    conditions(竞争条件——由于三个或者多个经过竞争使用不可能被同时做客的资源,使得这么些进程有可能因为日子上推进的次第原由此产出难点)。

  API网关可用于监视、限制和操纵对API的访问。以下内容可由网关或RESTful服务已毕。

  • 监视API的选用景况,并问询哪些活动是例行的,哪些是非正常的。
  • 界定API的采用,使恶意用户不能停掉一个API服务(DOS攻击),并且有能力阻止恶意的IP地址。
  • 将API密钥存储在加密的林芝密钥库中。

 

是您的品味

    非破坏性的改动

故而能关心自己生存的人,真的是最令人羡慕的▼

REST是什么?

  REST架构格局讲述了多样设计准则。那一个用于架构的宏图准则,最早是由罗伊Fielding在她的大学生小说中提出并定义了RESTful风格。(详见http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

  多个统筹准则分别是:

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

  以下是这么些规划准则的事无巨细谈论:

  ETag Header

本人不时讲大家的小孩子们,对生活里美的事物不够关切。其实您自己探讨,他们是哪有空去关爱。自己怎么活还来不及想,哪有空去关注生活。

排序

  排序决定了从服务端重临的记录的顺序。也就是对响应中的多条记下进行排序。

  同样,大家那里只考虑部分相比简单的境况。推荐应用排序字符串查询参数,它含有了一组用分隔符分隔的属性名。具体做法是,默许对每个属性名按升序排列,如果属性名有前缀”-“,则按降序排列。用竖线(”|”)分隔每个属性名,那和眼前过滤效果中的参数名/值对的做法一样。

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

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

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

 

就想让旁人见到买到这几个事物。

引言

平等我也羡慕阿峰的,是活着在塔那那利佛那样一座小城。

  行使Content-Location来拉长响应

是怎么着阻挡了俺们去搞点有意思的作业呢▼

本文主要读者

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

  本文中的指引规范一致适用于工程师们,他们盼望选拔这么些根据最佳实践标准开发的劳动。即使她们越来越关怀缓存、代理规则、监听及康宁等连锁地点,可是该文档能作为一份包涵所有品类服务的总指南。

  其它,通过从这个指点原则,管理人士精晓到创建公共的、提供高稳定性的劳动所需成本的着力,他们也可从中受益。

 

是您想跟她们分享的生存格局。

  DELETE

但作为一个生活形式店来说,阿峰的 Lighthouse
品味专一而引人深思,你又能在找到种种种种的,臭味相投的同伙。看到自己想过的生存的样板

  网站

俺们不是在找一个买东西的店,

  身份验证

玩什么的玩意儿

幂等性

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

在微机科学中,术语幂等用于更健全地叙述一个操作,四回或频仍举行该操作爆发的结果是同样的。依照使用的上下文,这或者有例外的含义。例如,在章程依然子例程调用装有副功效的情景下,意味着在率先调用之后被改动的场馆也保险不变。

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

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

假若讲我有一个叫@阿峰的朋友,在网上就有家不大不小的买手店。今日大家「探个店」这几个话题,就来聊聊
@阿峰 峰哥的买手店 Lighthouse ▼

结果限制

  “给出第3到第55条的笔录”,那种请求数据的格局和HTTP的字节范围规范更平等,由此我们得以用它来标识Range
header。而“从第2条记下起首,给出最多20条记下”那种艺术更易于阅读和透亮,由此大家常见会用字符串查询参数的章程来表示。

  综上所述,推荐既援救使用HTTP Range
header,也支持使用字符串查询参数——offset(偏移量)和limit(限制),然后在服务端对响应结果进行限制。注意,要是还要援救那二种办法,那么字符串查询参数的预先级要当先Range
header。

  那里你也许会有个难点:“那两种办法效果相似,可是回到的多少不完全一致。那会不会令人歪曲呢?”恩…那是多个难题。首先要回应的是,那实在会令人歪曲。关键是,字符串查询参数看起来更为清晰易懂,在打造和剖析时更加惠及。而Range
header则越来越多是由机器来选择(偏向于底层),它越是切合HTTP使用专业。

  总而言之,解析Range
header的工作会扩充复杂度,相应的客户端在打造请求时也亟需开展局地甩卖。而拔取单独的limit和offset参数会尤其便于了然和构建,并且不须要对开发人士有越多的要求。

哪能港?

书籍

  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.

一家店的魂魄是它的主理人,大家会不会欣赏这家店,取决于它所享受给我们的生活态度和生活形式是或不是能被大家所收取,前些天,我想带你认识阿峰和她的美式复古买手店。

资源命名

那是老板阿峰常常会说起的话。

  授权

那是后天在 JJJB
微信群里观察标一个谈谈,我以为蛮有意思的。如果单讲「性价比」和「基本款」的话,优衣库几乎是行业的样板,是更加极端的品牌

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

有好几自然的 Freestyle ▼

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

但阿峰自己不这么看。

查询,过滤和分页

旁人买的是你的审美,

资源命名

  除了适当地选择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:

但讲真,阿峰的 Lighthouse
店里的东西并没有有利的,那跟老董自己的审美情趣有着狠大关系 ▼

安全

  来自维基百科:

有的格局(例如GET、HEAD、OPTIONS和TRACE)被定义为安全的办法,那意味着它们仅被用来音讯搜索,而不能够改变服务器的景色。换句话说,它们不会有副成效,除了相对来说无害的熏陶如日志、缓存、横幅广告或计数服务等。任意的GET请求,不考虑采纳状态的上下文,都被认为是安全的。

  总而言之,安全意味着调用的主意不会唤起副功能。由此,客户端可以屡屡使用安全的呼吁而不用担心对服务端爆发其余副效能。那意味着服务端必须遵从GET、HEAD、OPTIONS和TRACE操作的汉中概念。否则,除了对消费端暴发模糊外,它还会促成Web缓存,搜索引擎以及任何活动代理的标题——那将在服务器上发出意想不到的结局。

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

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

 

境内的有些原创品牌和手工匠人们,跟阿峰所在的山西都林这么些地点也都怀有盘根错节的关系。

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

我们穿衣服毕竟仍然要走出门的。阿峰自己挑选的美式复古的着装,看起来要更为「日系」一点。按她的布道就是比较小清新的。

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

  有一个简短的法子可以解决这么些题材——在字符串中始终用平等的格式,包蕴时间片(带有时区音讯)。ISO8601时间格式是一个不易的解决方案,它应用了截然增强的时光格式,包含时辰、秒钟、秒以及秒的小数部分(例如yyyy-MM-dd’T’HH:mm:ss.SSS’Z’)。指出在REST服务的body内容中(请求和响应均包含)使用ISO8601代表所有的日期格式。

  顺便提一下,对于那么些基于JAVA的劳务来说,DateAdapterJ库使用DateAdapter,Iso8601TimepointAdapter和HttpHeader提姆estampAdapter类能够十分不难地分析和格式化ISO8601日期和岁月,以及HTTP
1.1
header(RFC1123)格式。可以从https://github.com/tfredrich/DateAdapterJ下载。

  对于那个创造基于浏览器的用户界面来说,ECMAScript5规范一先河就带有了JavaScript解析和创办ISO8601日期的内容,所以它应当改成大家所说的主流浏览器所听从的法门。当然,如若您要支持这一个不可能自动解析日期的旧版浏览器,可以利用JavaStript库或正则表明式。那里有多少个可以分析和创设ISO8601时间的JavaStript库:

  http://momentjs.com/

  http://www.datejs.com/

买得少一点,买得好一些。

按需编码(可选)

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

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

  提醒:REST架构中的安插性准则中,唯有按需编码为可选项。借使某个服务违反了其他随意一项准则,严酷意思上无法称之为RESTful风格。

 

你们说,是或不是其一道理?

  GET

别小看泉州那座小城,它是大家国家最大的衣服面料自由市场,也曾是最主要的行头生产基地,之一。

找出协理的本子

不装比,那在混「时尚」的圈子里是狠少见的。

REST火速提醒

  (按照上面提到的三个标准)不管在技术上是还是不是RESTful的,这里有一些近乎REST概念的指出。听从它们,可以完毕更好、更使得的服务:

有时候自己要好专门羡慕阿峰的,是他对团结卖的事物的思想。

查询,过滤和分页

  对于大数据集,从带宽的角度来看,限制再次来到的数据量是充足关键的。而从UI处理的角度来看,限制数据量也同等至关主要,因为UI常常只好彰显大数目集中的一小部分数量。在数据集的增加速度不确定的处境下,限制默许重返的数据量是很有必要的。以推特为例,要得到某个用户的推文(通过个人主页的时刻轴),若是没有尤其指定,请求默认只会回到20条记下,尽管系统最多能够重返200条记下。

  除了限制再次来到的数据量,大家还亟需考虑怎么着对命局据集进行“分页”或下拉滚动操作。创制数量的“页码”,重临大数额列表的已知片段,然后标出数据的“前一页”和“后一页”——这一作为被叫作分页。其它,大家可能也急需指定响应元帅包涵如何字段或品质,从而限制再次回到值的数量,并且大家愿意最后可以因此一定值来进展查询操作,并对重临值举办排序。

  有两种主要的艺术来还要限定查询结果和施行分页操作。首先,大家可以建立一个目录方案,它可以以页码为导向(请求中要付出每一页的记录数及页码),或者以记录为导向(请求中从来交给第一条记下和最终一条记下)来规定再次来到值的前奏地点。举个例子,这二种办法分别代表:“给出第五页(要是每页有20条记下)的笔录”,或“给出第100到第120条的笔录”。

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

  下文将介绍一种艺术,既可以辅助Dojo那样的分页形式(在请求头中付出记录的限制),也能援救选择字符串查询参数。那样一来服务端将变得进一步灵活,既可以动用类似Dojo一样先进的UI工具集,也足以选用简便直接的链接和标签,而无需再为此扩充复杂的支出工作。但假诺服务不直接协助UI作用,可以考虑不要在请求头中付出记录范围。

  要专门提出的是,大家并不推荐在富有服务中利用查询、过滤和分页操作。并不是享有资源都默许协助那一个操作,只有少数特定的资源才支撑。服务和资源的文档应当表达什么接口匡助那几个复杂的功力。

  安全

怎么是优衣库无法带给你的生活?

用范围标记举行界定

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

  Range: items=0-24

  注意记录是从0开端的两次三番字段,HTTP规范中证实了什么行使Range
header来请求字节。也就是说,假诺要哀告数据集中的率先条记下,范围应当从0开头算起。上述的伸手将会重返前25个记录,假若数据汇总至少有25条记下。

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

你们看!那年头哪个人还会听黑胶唱机呢?

结果的过滤和排序

  针对再次来到结果,还亟需考虑如何在服务端对数码举办过滤和排列,以及如何按指定的一一对子数据举办查找。那一个操作能够与分页、结果限制,以及字符串查询参数filter和sort等相结合,可以落成强大的数据检索功效。

  再强调一回,过滤和排序都是犬牙交错的操作,不必要默许提须要所有的资源。下文将介绍怎么着资源需求提供过滤和排序。

居然还有德意志Clearaudio的黑胶唱机 ▼

尊崇服务的鸡西

呼吁不援助的本子

  当呼吁一个不扶助的本子号时(包蕴在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-Type的链接

像「老朋友们」嘴里的
国棉壹厂,他们的工作室也就在阿峰工作室的邻座。和讯上更加红的胡先生的Pheather,起步的时候,也早就泡在艾哈迈达巴德小城的工作室里。

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

本来啦,也略微人是不太一致的。

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

遵守阿峰的说教,就是「硬汉啊,黑帮啊,匪徒啊」,都是长那些样子的 ▼

  应用程序安全

外加资源

用作复古圈的人的话,阿峰和她的 Lighthouse 太过清新,实在是一个异物。

    微小化链接推荐

远离香港(Hong Kong)、新加坡、柏林的快节奏和喧闹,能够小心在自己的生存上。

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

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

可怜硬。可是现代的审美看起来,走在中途总是哪儿怪怪的。

授权

  对服务的授权和对任何应用程序的授权一样,没有任何分裂。它依据那样一个题材:“主体是或不是对给定的资源有请求的许可?”那里给出了简短的三项数据(主体,资源和批准),因而很不难构造一个支撑这种概念的授权服务。其中重点是被赋予资源访问许可的人或系列。使用那个相似概念,就可以为每一个大旨营造一个缓存访问控制列表(ALC)。

实际上是太特么太鄙俗了。

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

你去阿峰店里逛过的话就会发觉,他们家的产品尤其杂。有澳大利亚(Australia)美利坚合营国带回去的复古品牌,也有日本引进回来的本地产品。还有像国棉壹厂,OverComer
那几个圈里有信誉的复古品牌,都跟阿峰的 Lighthouse 店有种种交集。

    破坏性的改动

黄铜和植鞣革手工制的水手皮带

    弃用

除却在卖衣服鞋子之类东西以外,阿峰也特地欣赏把温馨喜好的事物,强行放在店里。

PUT

  PUT平日被用来立异资源。通过PUT请求一个已知的资源URI时,须要在伸手的body中涵盖对原本资源的换代数据。

  然则,在资源ID是由客服端而非服务端提供的状态下,PUT同样可以被用来创设资源。换句话说,尽管PUT请求的URI中包罗的资源ID值在服务器上不设有,则用来创建资源。同时呼吁的body中必须带有要创立的资源的多少。有人觉得那会时有暴发歧义,所以只有真的须要,使用那种办法来创立资源应该被慎用。

  或者大家也可以在body中提供由客户端定义的资源ID然后使用POST来创立新的资源——要是请求的URI中不带有要开创的资源ID(参见上边POST的一对)。

  例如:

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

  当使用PUT操作更新成功时,会回来200(或者重回204,表示回去的body中不含有其余内容)。要是应用PUT请求创建资源,成功再次来到的HTTP状态码是201。响应的body是可选的——假若提供的话将会用度越来越多的带宽。在创造资源时并未必要通过尾部的义务重回链接,因为客户端已经安装了资源ID。请参见上面的重返值部分。

  PUT不是一个安全的操作,因为它会修改(或创制)服务器上的情况,但它是幂等的。换句话说,如若你使用PUT成立或者更新资源,然后再度调用,资源如故存在并且状态不会暴发变化。

  例如,如果在资源增量计数器中调用PUT,那么那几个调用方法就不再是幂等的。这种气象有时候会生出,且可能可以验证它是非幂等性的。可是,指出维持PUT请求的幂等性。并强烈提出非幂等性的请求使用POST。

  XML和JSON

过滤

  在本文中,过滤被定义为“通过特定的尺码来确定必要求赶回的数码,从而减弱重回的数额”。如果服务端匡助一套完整的可比运算符和错综复杂的口径合营,过滤操作将变得一定复杂。不过大家常见会动用部分简练的表明式,如starts-with(以…先导)或contains(包蕴)来拓展匹配,以管教重临数据的完整性。

  在我们开端谈论过滤的字符串查询参数以前,必须先清楚为啥要利用单个参数而不是多少个字符串查询参数。从根本上来说是为着减小参数名称的争论。大家曾经有offsetlimitsort(见下文)参数了。若是可能的话还会有jsonpformat标识符,或许还会有afterbefore参数,这几个都是在本文中涉嫌过的字符串查询参数。字符串查询中选拔的参数越多,就越可能造成参数名称的冲突,而利用单个过滤参数则会将争执的可能性降到最低。

  其它,从服务端也很不难仅经过单个的filter参数来判断请求方是或不是需求多少过滤效果。尽管查询需要的复杂度增加,单个参数将更具备灵活性——可以自己树立一套功能一体化的查询语法(详见下文OData注释或访问http://www.odata.org)。

  通过引入一组广泛的、公认的分隔符,用于过滤的表明式可以以更加直观的款式被应用。用那几个分隔符来设置过滤查询参数的值,这几个分隔符所制造的参数名/值对能够更加便于地被服务端解析并加强多少查询的特性。方今已有的分隔符包罗用来分隔每个过滤短语的竖线(”|”)和用来分隔参数名和值的双冒号(”::”)。那套分隔符丰硕唯一,并符合半数以上意况,同时用它来打造的字符串查询参数也越加不难驾驭。上面将用一个简短的例证来介绍它的用法。假如我们想要给名为“托德”的用户们发送请求,他们住在塔林,有着“Grand
Poobah”之称。用字符串查询参数达成的央求URI如下:

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

  双冒号(”::”)分隔符将属性名和值分开,那样属性值就可见包涵空格——服务端能更便于地从属性值中分析出分隔符。

  注意查询参数名/值对中的属性名要和服务端重返的属性名相匹配。

  简单而使得。有关大小写敏感的标题,要基于具体意况来看,但看来,在并非关切大小写的情况下,过滤效果可以很好地运行。若查询参数名/值对中的属性值未知,你也足以用星号(”*”)来代替。

  除了不难的表明式和通配符之外,若要举行更扑朔迷离的询问,你不可以不要引入运算符。在那种气象下,运算符本身也是属性值的一有的,能够被服务端解析,而不是成为属性名的一局地。当需求复杂的query-language-style(查询语言风格)成效时,可参看Open
Data Protocol (OData) Filter System Query
Option表明中的查询概念(详见http://www.odata.org/documentation/uriconventions#FilterSystemQueryOption)。

  分段系统

    用范围标记举办界定

    排序

  幂等性

    支持CORS

  基于资源

  差别资源须求用URI来唯一标识。重临给客户端的性状和资源本身在概念上有所差异,例如服务端不会一向传送一个数据库资源,然则,一些HTML、XML或JSON数据可见浮现部分数据库记录,如用希腊语来表达依旧用UTF-8编码则要按照请求和服务器达成的细节来控制。

分段系统

  客户端平常不可能声明自己是一贯或者直接与端服务器举行连接。中介服务器能够透过启用负载均衡或提供共享缓存来进步系统的延展性。分层时一样要考虑安全策略。

    基于范围的响应

维护服务的安全

  Authentication(身份验证)指的是认可给定的伸手是从服务已知的某人(或某个系统)发出的,且请求者是她协调所声明的极度人。Authentication是为了证实请求者的真人真事身份,而authorization(授权)是为着验证请求者有权力去执行被呼吁的操作。

  本质上,这些进程是这么的:

  1. 客户端发起一个请求,将authentication的token(身份表明令牌)包涵在X-Authentication
    header中,或者将token叠加在央浼的查询串参数中。
  2. 服务器对authorization
    token(授权令牌)进行检查,并开展表明(有效且未过期),并依照令牌内容分析或者加载认证要旨。
  3. 服务器调用授权服务,提供申明焦点、被呼吁资源和必备的操作许可。
  4. 假定授权通过了,服务器将会三番五次健康运转。

  上边第三步的开发可能会比较大,可是只要如若存在一个可缓存的权杖控制列表(ACL),那么在发生远程请求前,能够在地方制造一个授权客户端来缓存最新的ACLs。

接纳HTTP动词表示一些意思

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

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

网站

  http://www.restapitutorial.com
http://www.toddfredrich.com

  http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
  http://www.json.org/
https://github.com/tfredrich/DateAdapterJ

  http://openid.net/developers/specs/
  http://oauth.net/documentation/spec/
  http://www.json.org/JSONRequest.html
http://labs.omniti.com/labs/jsend

  http://enable-cors.org/
  http://www.odata.org/documentation/uri-conventions#FilterSystemQueryOption
  http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
  https://developer.linkedin.com/apis
  http://developers.facebook.com/docs/reference/api/
  https://dev.twitter.com/docs/api
http://momentjs.com/

  http://www.datejs.com/

 

在原翻译的基础上通过修改:http://blog.csdn.net/huayuqa/article/details/62237010

英文原文下载:RESTful Best Practices-v1
2.pdf

  包装响应

  利用HTTP动词表示一些意思

REST飞速提醒

缓存和可伸缩性

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

 

  通过特征来操作资源

  当客户端收到蕴涵元数据的资源的特征时,在有权力的情状下,客户端已精晓的足足的新闻,可以对服务端的资源进行删改。

外加资源

处理跨域难点

   大家都听说过有关浏览器的同源策略或同源性必要。它指的是浏览器只可以请求当前正在彰显的站点的资源。例如,假若当前正值彰显的站点是www.Example1.com,则该站点无法对www.Example.com倡导呼吁。显然那会影响站点访问服务器的措施。

  近期有五个被大面积接受的支撑跨域请求的主意:JSONP和跨域资源共享(CORS)。JSONP或“填充的JSON”是一种拔取格局,它提供了一个主意请求来自分裂域中的服务器的数量。其行事格局是从服务器再次回到任意的JavaScript代码,而不是JSON。客户端的响应由JavaScript解析器举办辨析,而不是一贯解析JSON数据。别的,CORS是一种web浏览器的技巧标准,它为web服务器定义了一种形式,从而允许服务器的资源可以被不一致域的网页访问。CORS被看做是JSONP的流行替代品,并且可以被有着现代浏览器支持。由此,不指出采用JSONP。任何动静下,推荐采取CORS。

无状态

  正如REST是REpresentational State
Transfer的缩写,无状态很重大。本质上,那标志了拍卖请求所需的状态已经包涵在伸手我里,也有可能是URI的一部分、查询串参数、body或底部。URI可以唯一标识每个资源,body中也含有了资源的转态(或转态变更景况)。之后,服务器将拓展拍卖,将相关的景观或资源通过头部、状态和响应body传递给客户端。

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

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

  在互连网利用的某一一定岗位上摆放一个回去按钮,是因为它希望你能按自然的一一来操作吗?其实是因为它违反了无状态的基准。有好多不信守无状态原则的案例,例如3-Legged
OAuth,API调用速度限制等。但仍然要尽可能保障服务器中不需求在四个请求下维持利用状态。

ETag Header

  ETag
header对于注解缓存数据的新旧程度很有用,同时也助长条件的读取和更新操作(分别为GET和PUT)。它的值是一个任意字符串,用来代表回到数据的版本。不过,对于重回数据的两样格式,它也得以分化——JSON格式响应的ETag与同样资源XML格式响应的ETag会差别。ETag
header的值可以像带有格式的底层域对象的哈希表(例如Java中的Obeject.hashcode())一样不难。指出为种种GET(读)操作重回一个ETag
header。别的,确保用双引号包涵ETag的值,例如:

  ETag: “686897696a7c876b7e”

 

理所当然的资源名

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

  适当的资源名称为服务端请求提供上下文,增添服务端API的可通晓性。通过URI名称分层地查看资源,可以给使用者提供一个团结的、不难了然的资源层次,以在他们的应用程序上选取。资源名称应当是名词,避免为动词。使用HTTP方法来指定请求的动作部分,能让事情更是的清晰。

自家应该同时援助多少个本子?

  维护五个不等的本子会让劳作变得繁琐、复杂、简单失误,而且代价高,对于其余给定的资源,你应该援救不当先2个版本。

  拍卖跨域难点

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

  REST指导标准之一(依照联合接口规范)是application的气象通过hypertext(超文本)来传输。那就是大家不足为奇所说的Hypertext
As The Engine of Application State
(即HATEOAS,用超文本来作为应用程序状态机),大家在“REST是什么”一节中也提到过。

  依照RoyFielding在他的博客中的描述(http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertextdriven),REST接口中最重点的片段是超文本的施用。此外,他还提出,在交付任何相关的新闻往日,一个API应该是可用和可清楚的。也就是说,一个API应当可以通过其链接导航到数码的次第部分。不提议只回去纯数据。

  不过当下的业界先驱们并没有平常利用那种做法,这体现了HATEOAS仅仅在成熟度模型中的使用率更高。纵观众多的服务连串,它们大多重回越来越多的多寡,而回到的链接却很少(或者尚未)。这是反其道而行之Fielding的REST约定的。Fielding说:“音信的每一个可寻址单元都指引一个地址……查询结果应该突显为一个分包摘要新闻的链接清单,而不是目的数组。”

  另一方面,不难残酷地将整个链接集合再次来到会大大影响互联网带宽。在实际上情状中,依据所需的原则或接纳情况,API接口的通讯量要按照服务器响应中国足球社团一级联赛文本链接所含有的“摘要”数量来平衡。

  同时,丰盛利用HATEOAS可能会大增完结的复杂性,并对劳动客户端发生显明的担当,这一定于下降了客户端和服务器端开发人员的生产力。因而,当务之急是要平衡超链接服务推行和现有可用资源之间的标题。

  超链接最小化的做法是在最大限度地压缩客户端和服务器之间的耦合的同时,进步服务端的可用性、可操纵性和可领悟性。那几个最小化提议是:通过POST创立资源并从GET请求再次来到集合,对于有分页的意况后边大家会波及。

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

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

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

  Offset参数的值与Range
header中的类似,也是从0发轫估算。Limit参数的值是再次回到记录的最大数量。当字符串查询参数中未指定limit时,服务端应当提交一个缺省的最大limit值,但是这么些参数的选用都亟待在文档中举办验证。

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

  以往,版本管理通过URI本身的版本号来落成,客户端在呼吁的URI中标明要得到的资源的版本号。事实上,许多大商家如推特、Yammer、非死不可、谷歌等不时在她们的URI里使用版本号。甚至像WSO2那样的API管理工具也会在它的URLs中须要版本号。

  面向REST原则,版本管理技术快速发展。因为它不包罗HTTP规范中放置的header,也不帮忙仅当一个新的资源或概念被引入时才应该添加新URI的观点——即版本不是表现情势的变化。另一个唱对台戏的理由是资源URI是不会随时间改变的,资源就是资源。

  URI应该能大致地辨别资源——而不是它的“形状”(状态)。另一个就是必须指定响应的格式(表征)。还有一对HTTP
headers:Accept 和 Content-Type。Accept
header允许客户端指定所希望或能支持的响应的传媒类型(一种或三种)。Content-Type
header可分别被客户端和劳动端用来指定请求或响应的数额格式。

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

  #Request:

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

  #Response:

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

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

  现在,大家对同一资源请求版本2的数额:

  #Request:

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

  #Response:

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

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

  Accept
header被用来代表所期望的响应格式(以及示例中的版本号),注意上述八个相同的URI是怎么形成在差其他本子中分辨资源的。或者,假设客户端需求一个XML格式的数据,能够将Accept
header设置为”application/xml”,即使必要的话也得以带一个点名的版本号。

  由于Accept
header可以被装置为允许二种传媒类型,在响应请求时,服务器将把响应的Content-Type
header设置为最匹配客户端请求内容的门类。越来越多消息可以参照http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.Html

  例如:

  #Request

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

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

  上述呼吁中,要是服务器匡助JSON
和XML格式的请求,或者两种都协助,那么将由服务器来控制最后回到哪种类型的数额。但无论服务器接纳哪种,都会在响应中包蕴Content-Type
header。

  例如,如若服务器重临application/xml格式的数额,结果是:

  #Response

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

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

  为了印证Content-Type在发送数据给服务器时的用处,那里给出一个用JSON格式创造新用户的例证:

  #Request

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

  {“name”:”Marco Polo”}

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

  #Request

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

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

统一接口

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

复数

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

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

 

  创造的资源名

    通过特征来操作资源

PUT和POST的始建相比

  不问可知,大家提出利用POST来创建资源。当由客户端来支配新资源具有哪些URI(通过资源名称或ID)时,使用PUT:即假如客户端知道URI(或资源ID)是如何,则对该URI使用PUT请求。否则,当由服务器或服务端来决定创办的资源的URI时则利用POST请求。换句话说,当客户端在创制以前不知情(或无法明白)结果的URI时,使用POST请求来创制新的资源。

  分页

HTTP动词

  Http动词首要坚守“统一接口”规则,并提要求大家相应的基于名词的资源的动作。最爱护仍然最常用的http动词(或者叫做方法,那样称呼可能更恰当些)有POST、GET、PUT和DELETE。那一个分别对应于创立、读取、更新和删除(CRUD)操作。也有不少其他的动词,然而利用频率比较低。在这一个应用较少的点子中,OPTIONS和HEAD往往选用得越来越多。

缓存和可伸缩性

  通过在系统层级消除通过中距离调用来赢得请求的数额,缓存升高了系统的可增加性。服务通过在响应中安装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

卷入响应

   服务器可以在响应中还要重返HTTP状态码和body。有很多JavaScript框架没有把HTTP状态响应码重返给最后的开发者,那频仍会促成客户端无法按照事态码来确定具体的行事。其它,尽管HTTP规范中有很各样响应码,不过频仍唯有个别客户端会关注那一个——平日大家只在乎”success”、”error”或”failture”。因而,将响应内容和响应状态码封装在含蓄响应音讯的风味中,是有必不可少的。

  OmniTI
实验室有诸如此类一个提议,它被称作JSEND响应。越来越多新闻请参考http://labs.omniti.com/labs/jsend。其余一个提案是由DouglasCrockford指出的,可以查阅那里http://www.json.org/JSONRequest.html

  那么些提案在实践中并不曾完全涵盖所有的动静。基本上,现在最好的做法是根据以下属性封装常规(非JSONP)响应:

  • code——包括一个平头类型的HTTP响应状态码。
  • status——包蕴文本:”success”,”fail”或”error”。HTTP状态响应码在500-599时期为”fail”,在400-499中间为”error”,其余均为”success”(例如:响应状态码为1XX、2XX和3XX)。
  • message——当状态值为”fail”和”error”时有效,用于呈现错误音讯。参照国际化(il8n)标准,它可以涵盖信息号或者编码,可以只含有其中一个,或者同时含有并用分隔符隔开。
  • data——包涵响应的body。当状态值为”fail”或”error”时,data仅蕴含错误原因或更加名称。

  上面是一个赶回success的卷入响应:

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

  重临error的包装响应:

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

  这四个包装响应对应的XML如下:

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

  和:

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

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

  然则上述提出仅适用于HTTP请求或响应内容中的JSON和XML内容,HTTP规范针对HTTP
headers使用另一种分裂的格式。在被RFC1123更替的RFC822中提议,该格式包含了各样日期、时间和date-time格式。然而,指出始终使用时间戳格式,在你的request
headers中它看起来像这么:

  Sun, 06 Nov 1994 08:49:37 GMT

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

 

    自描述的新闻

  呼吁不扶助的版本

HTTP动词

  POST

  资源命名的反例

  资源URI示例

正文首要读者

C-S架构

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

制造适当粒度的资源

  一初步,系统中模仿底层应用程序域或数据库架构的API更便于被创制。最后,你会愿意将这一个劳务都整合到共同——利用多项底层资源减少通讯量。在开创独立的资源之后再创立更大粒度的资源,比从更大的合集中创设较大粒度的资源更是不难一些。从部分小的简单定义的资源初步,创设CRUD(增删查改)功效,能够使资源的创设变得更便于。随后,你可以创建这一个依照用例和压缩通信量的资源。

据悉范围的响应

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

  自描述的信息

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

  找出支持的本子

再次回到表征

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

小小的化链接推荐

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

  对于从服务端再次来到的特征集合,每个表征应该在它的链接集合中教导一个细小的“自身”链接属性。为了便于分页操作,其它的链接可以放在一个独自的链接集合中回到,需要时得以分包“第一页”、“上一页”、“下一页”、“最后一页”等音讯。

  参照下文链接格式一对的例证获取越多音讯。

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

什么样时候应该创制一个新本子?

  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”}

 

设想连通性

  REST的原理之一就是连通性——通过超媒体链接完结。当在响应中回到链接时,api变的更富有自描述性,而在平素不它们时服务端如故可用。至少,接口本身可以为客户端提供什么寻找数据的参考。其余,在经过POST方法创设资源时,还足以应用头地点包罗一个链接。对于响应中帮助分页的汇集,”first”、
“last”、”next”、和”prev”链接至少是至极管用的。

 

  书籍

引言

  现今已有恢宏有关RESTful
Web服务至上实践的有关资料(详见本文最后的有关文献部分)。由于撰文的光阴各异,许多资料中的内容是顶牛的。其余,想要通过查看文献来打听那种劳动的腾飞是不太可取的。为了精晓RESTful这一定义,至少须要查阅三到五本有关文献,而本文将能够帮您加速这一进度——放任多余的座谈,最大化地提炼出REST的特级实践和标准。

  与其说REST是一套标准,REST更像是一种规格的集纳。除了五个紧要的标准化外就平昔不其余的正规了。实际上,即便有所谓的“最佳实践”和正式,但这么些东西都和宗派斗争一样,在频频地演化。

  本文围绕REST的科普难点提出了看法和仿食谱式的座谈,并通过介绍部分简单的背景知识对创立真实景况下的预生产环境中一样的REST服务提供文化。本文收集了来自其余渠道的新闻,经历过一回次的败诉后不断创新。

  但对于REST方式是不是必然比SOAP好用仍有较大争议(反之亦然),也许在某些景况下仍急需创建SOAP服务。本文在提及SOAP时并未花较大篇幅来谈谈它的对立优点。相反由于技术和行业在不断进步,我们将继续锲而不舍我们的只要–REST是当时安排web服务的一流方法。

  第一局地概述REST的意思、设计准则和它的出色之处。第二片段点数了一些小贴士来回想REST的劳动理念。之后的有些则会更长远地为web服务创建人员提供部分细节的支撑和座谈,来贯彻一个可以公开浮现在生育环境中的高质量REST服务。

 

劳动版本管理

   坦率地讲,一说到版本就会令人认为很艰巨,很麻烦,不太简单,甚至会让人以为悲伤——因为那会追加API的复杂度,并同时可能会对客户端爆发一些震慑。因而,在API的宏图中要尽量幸免多少个分化的本子。

  不辅助版本,不将版本控制作为糟糕的API设计的借助。固然你在APIs的布置性中引入版本,那迟早都会让您抓狂。由于再次来到的数目通过JSON来表现,客户端会由于差其他本子而接受到分歧的特性。那样就会存在部分题材,如从内容我和验证规则方面改变了一个已存在的性质的意义。

  当然,大家鞭长莫及避免API可能在一些时候需求变更重临数据的格式和情节,而那也将造成消费端的部分扭转,我们应有幸免举行部分非同儿戏的调整。将API举办版本化管理是幸免那种根本变动的一种有效措施。

  结果限制

    基于资源

定义

  PUT和POST的成立相比较

应用Content-Location来拉长响应

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

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

  可缓存

定义

  结果的过滤和排序

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暴光不安全的操作——它应该永远都不可以改改服务器上的其余资源。

  考虑连通性

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

分页

  上述办法通过请求方指定数据集的限定来界定再次来到结果,从而完毕分页作用。下面的事例中累计有66条记下,如若每页25条记下,要显得第二页数据,Range
header的情节如下:

  Range: items=25-49

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

  GET …?offset=25&limit=25

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

  Content-Range: 25-49/66

  在多数景况下,那种分页格局都未曾难点。但有时会有那种场合,就是要回去的记录数据不可能直接代表成数据汇总的行号。还有就是有些数据集的变更很快,不断会有新的多寡插入到数量集中,那样必然会促成分页出现难点,一些重新的数量可能会现出在分歧的页中。

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

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

    链接格式

  无状态

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

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

  除了上述情节外,HATEOS也表示,须要的时候链接也可被含有在回去的body(或底部)中,以提供URI来查找对象自我或涉及对象。下文将对此举行更详尽的演讲。

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

  C-S架构

劳动版本管理

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

回去表征

 

日子/时间处理

POST

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

  例如:

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

  当成立成功时,重回HTTP状态码201,并顺便一个义务头新闻,其中含有指向开首创设的资源的链接。

  POST请求既不是安全的又不是幂等的,因而它被定义为非幂等性资源请求。使用七个一样的POST请求很可能会造成创设八个饱含相同信息的资源。

弃用

  Deprecated(弃用)的目标是用来阐明资源对API照旧可用,但在以后会不设有并变得不可用。只顾:弃用的时长将由弃用政策决定——那里并没有交给定义。

可缓存

  在万维网上,客户端可以缓存页面的响应内容。由此响应都应隐式或显式的概念为可缓存的,若不足缓存则要幸免客户端在频仍伸手后用旧数据或脏数据来响应。管理得当的缓存会部分地或完全地除了客户端和服务端之间的并行,进一步校订品质和延展性。