且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我应该为 REST API 集合使用数组还是对象?

更新时间:2023-09-08 15:24:52

您在问题中声明:

这是一个一般性问题,需要了解哪个看起来更像是***实践",而不假设客户端如何查询/使用 REST API.

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

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

[{英语语言",书":[{"title": "第一个标题","content": "第一个内容"}]},{"language": "法语",书":[{"title": "***名额","content": "总理续集"}]}]

然而,本质上,除了使它们有用"之外,对于您正在构建的数据结构没有单一的***实践.

My API contains a Book entity which represents a collection of several possible BookContent depending on the language. A BookContent is another entity with the attributes Title and Content, which both depend on the Language.

Should a Book look like:

1)

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

or like:

2)

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

The option 1):

  • produces "self-contained" elements, i.e. each object contains all the information.
  • The language attribute can contain any Unicode character (whereas as a key it cannot).
  • is the only available option if the content depends on multiple criteria, i.e. language and year.
  • creates a clearer separation between the two entities. For example, it makes it easier to replace each element by its ID, if we were to decide not to embed the BookContent entity anymore but only return the BookContent ID.
  • is probably more familiar to developers using my API, since I believe it is more common to find this kind of structure in other REST APIs.

The option 2):

  • produces smaller elements.
  • makes it faster to look for the elements according to the language without traversing through the whole collection.

This is a general question to know which one looks more like a "best practice", with no assumption on how the clients are querying/using the REST API, nor how much performance matters as opposed to flexibility, etc.

Which option is generally more often a "best practice"?

You state in your question that:

This is a general question to know which one looks more like a "best practice", with no assumption on how the clients are querying/using the REST API.

You are writing a REST service that is designed to help clients get information out - if that wasn't your aim, there'd be no point writing it. Because of this, the most important question you need to answer is "what information do clients want?". The answer to that will dictate the structure of your data, not "which one looks better?" - we're not your service's end users.

Personally, I'd opt for the first, simply because it would seem wrong to have an array called books.English in my object, it also allows for languages with characters outside of A-Z, and caters for books where the language is not known (or mixed). If simplicity of the individual book is key (and the list of languages is well-defined and finite), then consider:

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

In essence, however, there's no single best practise for the data structures you're building other than "make them useful".