在rest api中使用数组展平的嵌套资源?

时间:2016-05-26 12:34:37

标签: api rest

我需要为复杂的嵌套资源提供REST API。

我不太喜欢内联嵌入,因为它会强制数据重复响应,这会使响应更大,更难以被前端解释(例如,几个车可以有单引擎,但我需要在响应中复制它)

GET /cars
{
  "cars": {
    "id": 1,
    "name": "Batmobile",
    "spoiler": 192, // nested
    "engine": 18 // nested
  },
  "engines": {
    "id": 18,
    "turbine": 671 // nested
    ...
  },
  "spoilers": {
    "id": 192,
    ...
  },
  "turbines": {
    "id": 671,
    ...
  }
}

我想使用以下格式,因为:

  • 数据已标准化
  • 数据可轻松与angular2数据存储集成

Hovewer,我无法找到任何标准或任何实现此类格式的REST API提供商。所有标准通常都使用内联嵌入。

有没有没有实施这样的协议?

2 个答案:

答案 0 :(得分:1)

根据我对你的帖子的理解,你想要展平什么,否则它本身就是一个嵌套文档的文档。

我看不出扁平化如何增强可读性。此外,它是非正统的,将阻碍API的理解。

在您的示例中,您正在请求GET /cars,但您正在检索汽车和所有相关资源作为第一级项目。您将如何访问和更新个人资源?

由于以下几个原因,必须将资源嵌套和/或分解到不同的端点:

  1. 客户通常不会在一个请求中需要所有汽车及其所有部件。它通常会导航资源,从汽车开始,然后是汽车细节,然后是零件。
  2. 在具有特定语义的单独URI上分离资源有助于将这些资源与资源上的CRUD操作对齐。对于您的扁平化表示,这将非常困难。
  3. 不同资源在不同的URI上,每个URI都有独立的表示形式,可帮助您管理API并包含更改并减少耦合
  4. 如果您正在尝试构建REST API,那么您建议的展平表示最终会弄乱它们。
  5. 我建议:

    1. 您将相关资源呈现为链接(HAL中的行):

      GET /cars [ { "name": "Batmobile", "links": [ { "rel" : "self", "href": "https://api.superauto.com/cars/1" }, { "rel" : "spoiler", "href" : "https://api.superauto.com/spoilers/192" }, { "rel": "engine", "href": "https://api.superauto.com/engines/18" } ] } ]

    2. 您将每个资源分开放在不同的URI中

    3. 您坚持使用RESTful API设计。查看REST API TutorialRestful best practices

    4. 有支持HAL的库(至少在JVM生态系统中:Java,Groovy,Scala,Kotlin)。如果此表示不符合您的所有需求,您还可以使用支持基于每个请求嵌入资源的库,因此您可以覆盖默认响应嵌入相关资源。

答案 1 :(得分:-1)

normalizr可以帮助您更轻松地将其集成到angular2数据存储中。