我应该使用数组或对象来进行REST API集合吗?

时间:2015-01-05 12:52:21

标签: rest collections model

我的API包含一个Book实体,它根据语言表示几个可能BookContent的集合。 BookContent是具有TitleContent属性的另一个实体,它们都依赖于Language

Book应该是这样的:

1)

[
  {
     "language": "English",
     "title": "First title",
     "content": "First content"
  },
  {
     "language": "French",
     "title": "Premier titre",
     "content": "Premier contenu"
  }
]

或者喜欢:

2)

{
  "English": {
     "title": "First title",
     "content": "First content"
  },
  "French": {
     "title": "Premier titre",
     "content": "Premier contenu"
  }
}

选项1):

  • 生成“自包含”元素,即每个对象包含所有信息。
  • language属性可以包含任何Unicode字符(而不能作为密钥)。
  • 如果内容取决于多种标准,即语言和年份,则
  • 是唯一可用的选项。
  • 在两个实体之间创建更清晰的分离。例如,如果我们决定不再嵌入BookContent实体,只返回BookContent ID,则可以更容易地用ID替换每个元素。
  • 使用我的API的开发人员可能更熟悉
  • ,因为我认为在其他REST API中找到这种结构更为常见。

选项2):

  • 产生更小的元素。
  • 可以更快地根据语言查找元素,而无需遍历整个集合。

这是一个普遍的问题,要知道哪一个看起来更像是“最佳实践”,没有假设客户端如何查询/使用REST API,也没有假设性能如何与灵活性等相关。

哪种选择通常更像是“最佳做法”?

1 个答案:

答案 0 :(得分:3)

您在问题中说明:

  

这是一个普遍的问题,要知道哪一个看起来更像是“最佳实践”,而不考虑客户端如何查询/使用REST API。

您正在编写旨在帮助客户获取信息的REST服务 - 如果这不是您的目标,那么编写它就没有意义。因此,您需要回答的最重要的问题是“客户想要什么信息?”。 的答案将决定数据的结构,而不是“哪一个看起来更好?” - 我们不是您服务的最终用户。

就个人而言,我会选择第一个,因为在我的对象中有一个名为books.English的数组似乎是错误的,它还允许使用AZ以外的字符的语言,并适用于语言未知(或混合)的书籍。如果单个书的简单性是关键(并且语言列表是明确定义且有限的),那么请考虑:

[
    {
        "language": "English",
        "books": [{
            "title": "First title",
            "content": "First content"
        }]
    },
    {
        "language": "French",
        "books": [{
            "title": "Premier titre",
            "content": "Premier contenu"
        }]
    }
]

然而,从本质上讲,除了“使它们有用”之外,对于您正在构建的数据结构没有单一的最佳实践。