专栏首页机器学习与系统RESTful API模式系列三:资源

RESTful API模式系列三:资源

说明

  • 原文链接:http://restful-api-design.readthedocs.io/en/latest/resources.html
  • adolphlwq:https://github.com/adolphlwq
  • 项目地址:https://github.com/adolphlwq/translate
  • 翻译/校对:3.5h
  • 知识共享许可协议: CC4.

资源是任何RESTful API中的基本概念。资源是对象,包括类型、关联的数据、资源间的关系以及资源上的操作集合。它和面向对象编程语言中的对象类似,不同点在于资源 只定义了有限的标准方法(对应HTTP协议中标准的GET,POST,PUT,DELETE方法),而对象实例可以有很多方法。

资源可以被分类到不同的集合中。每个集合都包含一种类型的资源,因此集合都是均匀(homogeneous)的。资源也可以不分到集合里,这些资源我们称为singleton resources

集合可以全局存在,即API顶层(译者注:原文at the top level of an API),也可以包含在single resource中。后文中,我们把这种集合称为sub-collections,子集通常用来表达“包含于”的关系。我会在Relationships详细介绍。

下图描述了RESTful API的关键概念:

我们把描述资源的类型、行为和关系的信息称为API的资源模型。RESTful中的资源模型可以视为到应用数据模型的映射。

资源数据

资源关联数据。API的资源模型还包括关联数据的丰富性。比如,它定义了哪些可用的数据类型和行为。

就我个人经验,我坚信JSON这种数据模型完美满足API的丰富性要求,它是RESTful资源的理想数据模型。我会推荐给每个人。

JSON中已经存在三种类型数据:

  • scalar(标量:number, string, boolean, nul)
  • array
  • object

标量类型只有一个值。数组包含任意类型值的有序列表。对象是无序的key/value(键/值对)集合(亦称为属性,但是不要和XML中的属性概念搞混),key是字符串,value可以是任意类型。更多JSON细节请参考JSON web site。

为什么如此偏爱JSON?以我个人观点,JSON在表达性和广泛应用上拥有良好的平衡。scalars、arrays和objects这三种类型足够强大,能够以自然的方式描述资源中暴露的数据,同时JSON足够小巧,几乎任何现代语言都可以内置支持JSON。

XML也是以为有力的竞争者(contender)。实际上,RHEV-M(译者注:红帽的一款产品)最终API中就使用XMLSchema来描述资源。事后来看(With hindsight),RESTful API使用XML模型是个糟糕的选择。一方面,它过于丰富;另一方面,它又缺少一些特性。XML作为标准通用标记语言的一个分支(SGML off-shoot),我认为它在表示结构化文档是伟大的,但是不适合表示结构化数据

XML一些过于丰富的特性有:

  • Attributes vs elements(属性与元素)。XML可以既有属性,也包含子元素。包含数据项的资源可以被编码成任意一种。这导致客户端或者服务端事先不清楚该使用哪一个。
  • Relevance of order(顺序相关性)。子元素间的顺序也会关联到XML中,我认为对象间的属性就不是自然的有序了

XML数据模型的缺点有:

  • 没有类型。XML文档中的元素没有类型,为了使用类型需要引入XMLSchema,不幸的是XMLSchema规范非常复杂。
  • 没有列表。XML不能原生表达列表。这可能导致问题:不清楚某个元素是列表还是对象,或者两者都是。

应用数据

我们使用以下规则定义可以与JSON数据模型映射的资源数据:

  1. 资源被建模为JSON对象。资源的类型存储在特殊的键值对_type中。
  2. 资源中的数据表示为JSON对象中的键值对。为了避免和JSON对象内部键值对冲突,键不能以“_”开头
  3. 键值对中的值可以是JSON中任意原生类型: string、number、boolean、null或者arrays。值还可以是对象,这种情况下值表示嵌套的资源。
  4. 集合表示成对象数组。

我们也会把键值对认为JSON对象中的属性,这里不详细描述区别,都使用统一的术语。这样JSON中的属性就不会和XML中的属性冲突了。

REST元数据

除了暴露应用数据,资源中还有RESTful API相关特殊的数据。这些信息包括URLs和relationships。

下表列出了所有资源中定义的,通用、有特殊含义的属性:

Attribute

Type

Meaning

id

String

Identifies the unique ID of a resource

href

String

Identifies the URL of the current resource

link

object

Identifies a relationship for a resource. This attribute is itself an object and has “rel” “href” attributes

其它数据

通常,除了应用数据、REST元数据外,我们还需要一些数据。这通常是“类RPC”数据,其中需要设置操作,但是设置最终不会作为资源本身一部分。

这里我能列举的例子是,创建新资源过程中需要引用另一个资源,但是被引用的资源最终不会成为创建资源的一部分。

将应用数据、REST元数据和其它数据合并到资源中是API代码的职责,有可能要解决可能出现的名称冲突的问题。

表示

我们已经定义了资源,同时也介绍了资源数据和JSON数据模型间的映射关系。但是,这些资源仍然是抽象的实体。在它们通过HTTP链接和客户端通信前,它们需要被序列化成文本表现形示。然后这种文本表示就可以作为实体包含在HTTP消息体中。

以下表示类型是资源常用的,该表还可使用的内容类型:

Type

Content-Type

JSON

application/x-resource+json application/x-collection+json

YAML

application/x-resource+yaml application/x-collection+yaml

XML

application/x-resource+xml application/x-collection+xml

HTML

text/html

注意:所有使用x-前缀的内容类型都是实验阶段,RFC2046也是认可的。

JSON格式

将资源序列化为JSON格式很简单,因为资源的数据模型是根据JSON模型定义的。下面我们给出一个虚拟机JSON序列化的例子:

{
 "_type": "vm",
 "name": "A virtual machine",
 "memory": 1024,
 "cpu": {
   "cores": 4,
   "speed": 3600
 },
 "boot": {
   "devices": ["cdrom", "harddisk"]
 }
}

YAML格式

YAML格式和JSON稍微不同,JSON中键值对里的“_type”在YAML中替换为“!type”注解。上面的虚拟机实例的YAML格式为:

!vm
name: A virtual machine
memory: 1024
cpu:
 cores: 4
 speed: 3600
boot:
 devices:
 - cdrom
 - harddisk

XML格式

由于XML的复杂性和限制,XML表示法是最复杂的。我推荐下面的规则:

  • 资源映射到XML元素,加上标签名表示资源类型。
  • 资源属性映射到XML子元素,标签名表示属性名。
  • 标量表示成文本节点。标量元素中关键字“type”表示标量类型,这种映射要遵守XML Schema Part 2。
  • 列表要存储为单个的容器元素,其中每个列表项都有子元素。容器元素的标签应当是属性名称英文复数,item标签应该是属性名称的英文单数。列表应该具有“xd:list”类型注释。

相同的虚拟机资源的XML表示格式为:

<vm xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <name type="xs:string">My VM</name>
 <memory type="xs:int">1024</memory>
 <cpu>
   <cores type="xs:int">4</cores>
   <speed type="xs:int">3600</speed>
 </cpu>
 <boot>
   <devices type="xs:list">
     <device type="xs:string">cdrom</device>
     <device type="xs:string">harddisk</device>
   </devices>
 </boot>
</vm>

HTML格式

HTML响应的精确格式应该是API相关的。HTML是为人类使用设计的,因此唯一要求是易于理解。一个简单实现可以是下面的表示法:

  • 对于集合,使用<table>标签表示,每一列表示一个属性,每一行表示一个对象。
  • 对于资源,使用<table>标签和两列表示,一列表示所有的属性名,一列表示属性对应的值。

Content-Types

根据上文内容,我主张使用的通用内容类型是“application/x-resource+format”和“application/x-collection+format”。在我看来,它们代表了RESTful API中常见的两个极端情形的中间情形:

一类RESTful API只使用“空的”(译者注:bare)XML、JSON或者YAML内容类型。这种情况下,内容类型只表示实体的类型是XML、JSON或者YAML。在我看来,这依然不够。因为资源和集合会有一些特定的语义,例如“href”属性,“link”属性和type。Therefore, these are a specialization of XML, JSON and YAML and should be defined as such(译者注:这里不翻译是因为没看懂)。

另一类RESTful API会为资源模型中的每个资源类型都定义内容类型。一个例子是vSphere Director API。在我看来这也不妥。指定详细的内容类型会导致API方和客户端方认为这些类型有特定的接口。我认为所有的资源应该共享那些相同的、基本的接口,这些基本接口是符合RESTful设计原则,内容类型表示为“application/x-resource”。

一个原因是,通过 有利于内容类型 细节定义 的方法,内容类型可以和某些类型定义语言(如XMLSchema)中的属性相关连。据推测,这有利于客户端自动发现,因为客户端知道某种类型的可用属性。我在Forms讨论(go into)了很多这个主题的细节,但总结下来我并不统一这个论点。

选择表式格式

客户端可以通过HTTP“Accept”头表示客户端使用哪种合适。HTTP RFC声明了详尽的规则,规则中可以请求多种格式,没中格式都有自己的优先级。下面的例子中客户端告诉API它只接受YAML格式:

GET /api/collection
Accept: application/x-collection+yaml

译者说

本文在HTTP协议的背景下,介绍了RESTful中的资源包含那些类型的数据;资源与JSON、XML、YAML等格式间的映射规则。作者支持将资源映射称JSON格式。 阅读本文还需要了解HTTP协议,否则很多属于很难理解。

本文分享自微信公众号 - 机器学习与系统(aimlsystem),作者:adolphlwq

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-03-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [翻译]RESTful API设计系列三:URLs

    RESTful API有且只有一个入口点(entry point)。入口点的URL要告知API客户端,以便它们可以找到。

    陆道峰
  • [翻译]RESTful API模式系列二:API设计者的职责

    在完全深入RESTful API设计之前,详细了解RESTful API设计者的工作细节很重要。

    陆道峰
  • Spring+SpringMVC+MyBatis+easyUI整合进阶篇(一)设计一套好的RESTful API

    写在前面的话 看了一下博客目录,距离上次更新这个系列的博文已经有两个多月,并不是因为不想继续写博客,由于中间这段时间更新了几篇其他系列的文章就暂时停止了,如今已...

    程序员十三
  • 带你了解OData

    OData - Open Data Protocol,是一个设计和使用RESTful API的标准。REST本身只是一个构建web服务的思想和理念,其没有规定一...

    matinal
  • Spring Boot入门系列(二十)快速实现Restful API 接口

    随着互联网化等逐渐深入,应用系统也变得越来越复杂,系统架构正在朝着微服务化,中台化的方向发展。这就需要各个系统、各个厂家之间的数据频繁交互。所以,使用 Rest...

    架构师精进
  • 正确甄别API、REST API、RESTful API和Web Service之间的异同

    看到API你会想起什么?是接口、第三方调用、还是API文档?初看你可能会觉得这太熟悉了,这不是系统开发日常系列吗?但你仔细想一想,你会发现API的概念在你脑海里...

    IT大咖说
  • 使用 swagger 生成规范化的RESTful API 代码

    REST(英文:Representational State Transfer,又称具象状态传输)是Roy Thomas Fielding博士于2000年在他的...

    goodspeed
  • 使用 swagger 生成Flask RESTful API

    REST(英文:Representational State Transfer,又称具象状态传输)是Roy Thomas Fielding博士于2000年在他的...

    goodspeed
  • 为什么应该使用RESTful Web服务设计

    你可能负责一个API。也许你正准备投入制作一个,并且很期待开始。但是要小心,因为好的API设计可能很难。

    程序你好
  • RESTful API教程:学习关键的Web服务设计原则

    原题:RESTful APIs tutorial: Learn key web service design principles

    yuanyi928
  • Angular企业级开发(4)-ngResource和REST介绍

    一、RESTful介绍 ? RESTful维基百科 REST(表征性状态传输,Representational State Transfer)是Roy Fie...

    八哥
  • RESTful API生命周期管理

    介绍 应用程序编程接口(API)设计自计算机早期就已经存在 - 程序员不久之后就意识到明确定义的一组方法或功能有助于促进方案交流。虽然各种API之间的规格有所...

    用户1263954
  • k8s源码分析(2)- kube-apiserver

    上一篇整理了client-go框架的Informer机制,informer源码分析, 同时api-server用到了go-restful这个web框架,go-r...

    kinnylee
  • 程序员入职避免挨骂小知识-RESTful风格

        API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同...

    XiaoLin_Java
  • Restful 架构 API 接口经典设计误区

    目前微服务架构盛行,在了解了很多的实际微服务项目中,发现很多同事在设计业务 API 接口时,写法五花八门,现总结下目前项目上设计业务 API 接口的一些比较经典...

    猿芯
  • 深入理解什么是RESTful API ?

    越来越多的人开始意识到,网站即软件,而且是一种新型的软件。   这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(hi...

    AWeiLoveAndroid
  • 深入理解什么是RESTful API ?

    越来越多的人开始意识到,网站即软件,而且是一种新型的软件。   这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(hig...

    竹清
  • 【译】构建RESTful API的13种最佳实践

    Facebook、GitHub、Google 以及其他许多巨头都需要一种服务和消费数据的方式。在当今的开发环境中,RESTful API 仍然是服务和消费数据的...

    张张
  • 细说RESTful API之入门介绍

    REST(英文:Representational State Transfer,又称具象状态传输)是Roy Thomas Fielding博士于2000年在他的...

    编程随笔

扫码关注云+社区

领取腾讯云代金券