JSON API 实体是否应该包含其父实体的关系?

Should JSON API entities include a relationship for its parent?

一直没有找到明确的答案,希望有人能帮忙。

如果我们有一个博客 post,每个 post 可以有评论,每个评论都有一个相关的用户。如果我请求评论,将用户 和 post 都包含在关系中是否违反惯例?

data: {
  type: 'comments',
  id: '1',
  relationships: {
    post: {...}, //should this be here?
    user: {...},
  }
  attributes: {...},
},
included: {...}

问:JSON API 实体是否应该包含其父实体的关系?

A:我想这完全取决于你!

如果您的 JSON 是由某些第三方定义的,那么您必须忍受他们给您的东西。请 post 详细说明 JSON 是如何指定的。

否则,如果您是"inventing"自己的格式:

  1. 一种可能性是 relationships: 字段带有 link 到 "parent"。

  2. 也许更好的解决方案可能是发明一个 "container"(也许是一个简单的数组!)来保存你的 "records".

  3. 如果这是一个数据库,我会有一个 "posts" table 和一个 "comments" table。 "comments" table 将有一个 "Post ID" 列作为外键进入 "posts" table.

'希望有所帮助...至少有一点...

paulsm4 正确表述:"it is up to you".

不过我可以给你一些建议。

在这种情况下,您可以通过查询字符串标志让 API 的调用者选择是否具有此类链接,例如

?relationships=post,user

在这种情况下,如果您不指定关系标志,您将获得简单的评论数据,或者您可以决定全部提供;在第二种情况下,您可以使用 relationships 作为一种过滤器。

在某些 API 中,我还看到了一种更具侵入性的方法:将相关对象直接嵌入到返回的 JSON 中。

使用与之前相同的技术:

?embed=post,user

这应该会在当前 JSON 回复中生成一个嵌入的 JSON 对象,包括原始对象,就像您分别询问 "GET /post/123" 或 "GET /user/456" 之类的内容一样。这在某些情况下会很方便。

通常此标志被命名为 "expand" 表示相同或相似的行为。

例如,打开 this API documentation from Atlassian 并搜索 "expand"。

对于您的问题 HAL,确实存在一个旧的 "standard",它谈到了在 REST API 中的链接和嵌入。

甚至 Wordpress API 也提供了这样的功能,请在 official documentation.

中查看一下

另一种方法是利用 REST 方法在 GraphQL 中重写整个 API。

JSON API规范对属性关系没有做任何要求资源对象。规范只是说明如果包含它们必须如何格式化。如果我没有遗漏任何东西,规范甚至不要求相同类型的所有 资源对象 必须具有相同的 属性 关系.

但我认为不包括这些关系没有任何价值。 JSON API 规范不需要 relationship object to include resource linkage data. On the contrary it's only talking about resource linkage data in context of a compound document,其中使用了 "to link together all of the included resource objects without having to GET any URLs via links."

如果相关资源未包含在负载中,则仅提供 related resource link 是完全有效的,可以被视为最佳实践。构建这样一个 link 不会给您的服务器带来任何工作量,因为它不需要查询数据库。它也不会在有效载荷大小上产生任何相关差异。

使用这两种技术的负载示例如下所示。它假定请求明确要求使用 include query param.

包含相关用户
// GET https://examples.com/api/v1/comments/1?include=user

{
  data: {
    type: 'comments',
    id: '1',
    relationships: {
      post: {
        links: {
          related: 'https://examples.com/api/v1/comments/1/post'
        }
      },
      user: {
        data: {
          type: 'users',
          id: '2'
        },
        links: {
          related: 'https://examples.com/api/v1/comments/1/user'
        }
      },
    }
  },
  included: [
    {
      type: 'users',
      id: '2',
      attributes: {
        name: 'John Doe'
      }
    }
  ]
}

您可能还想包括一个 relationship link, which "allows the client to directly manipulate the relationship." Update relationships chapter 规范,深入了解您可以使用关系 link 完成什么。