在rest api中数组扁平化嵌套资源



我需要为复杂的嵌套资源提供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提供程序。所有标准通常都使用内联嵌入。

不执行这样的协议有什么缺点吗?

根据我对您的文章的理解,您希望将原本是带有嵌套文档的文档压扁。

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

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

将资源嵌套和/或分解为不同的端点是必要的,原因有几个:

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

我建议:

  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教程和Restful最佳实践

有一些库(至少在JVM生态系统中:Java、Groovy、Scala、Kotlin)支持HAL。如果这种表示不能满足您的所有需求,您还可以使用支持在每个请求的基础上嵌入资源的库,这样您就可以覆盖默认的响应嵌入相关资源。

normalizr可以帮助更容易地将其集成到angular2数据存储中。

最新更新