【问题标题】:JSON API relationship with meta informationJSON API 与元信息的关系
【发布时间】:2020-07-11 05:17:34
【问题描述】:

我有一个实体 contract,关系为 contract_contacts,应该以 JSON API 格式呈现。

为了更清楚,这里是我的实体的结构:

合同

  • 身份证
  • 姓名

合同联系方式

  • contract_id
  • contact_id
  • 类型
  • 评论

联系方式

  • 身份证
  • 姓名

可能的 JSON API 输出如下所示:

{
    "data": {
        "type": "contracts",
        "id": "1",
        "attributes": {
            "name": "Contract 1"
        },
        "relationships": {
            "contacts": {
                "data": [
                    {
                        "type": "contract_contacts",
                        "id": "1"
                    },
                    {
                        "type": "contract_contacts",
                        "id": "2"
                    }
                ]
            }
        }
    }
}

这种方法还不够好 - 您必须为关系创建额外的资源,您将在其中存储您的联系人和带有类型的评论。您必须包含 2 个级别的深度才能获得联系字段。同样在这种情况下,创建contract 前端应该同时使用这两种资源:

  1. 创建合同联系人并获取 ID
  2. 然后创建具有关系的合同 上面有id

第二种方法对我来说似乎hacky,因为它会使用meta,如何使用它取决于你。示例:

{
    "data": {
        "type": "contracts",
        "id": "1",
        "attributes": {
            "name": "Contract 1"
        },
        "relationships": {
            "contacts": {
                "data": [
                    {
                        "meta": {
                            "comment": "comment 1",
                            "type": 1
                        },
                        "type": "contacts",
                        "id": "10"
                    },
                    {
                        "meta": {
                            "comment": "comment 2",
                            "type": 2
                        },
                        "type": "contacts",
                        "id": "11"
                    }
                ]
            }
        }
    }
}

这种方法将简化前面示例中的 api 请求的混乱情况。

但是对于带有元字段的 POST/PUT/PATCH 是否正确,因为它们不应该从客户端(或不应该)更改?我对这部分感到困惑。

【问题讨论】:

    标签: api json-api


    【解决方案1】:

    您所描述的关系通常被称为 has-many-through 关系:contract 有许多 contactscontract_contacts。这些被定义为通过中间资源链接两个资源的关系。

    JSON:API specification 不为此类关系提供一级支持。相反,您应该通过单独的资源对它们进行建模,如您所描述的作为您的第一个选项。这允许您以与任何其他资源相同的方式创建、修改和删除您的中间资源。这样做可以降低复杂性,因为中间资源只是另一种资源类型。

    您提到了这样做的两个问题:

    1. 您必须包含 2 个级别的深度才能获得联系字段。

      这是真的,但不应该成为问题。 include 查询参数允许您的客户端根据需要将资源侧载到任何深度。如果中间资源的信息存储在关系本身上,则响应文档可能会稍大一些,但在 gzip 之后不应该与生产相关。

    2. 同样在这种情况下,创建合同前端应该同时使用两种资源:

      1. 创建合同联系人并获取 ID
      2. 然后从上面创建具有 id 关系的合同

      这是对当前稳定版 JSON:API 规范 (v1.0) 的严重限制。因此,它与 has-many-through 关系没有直接关系。这是规范的一般限制,不支持一次请求创建、修改和/或删除多个资源。

      针对规范的 v1.1 提出了官方 Atomic Operations extension 以解决该限制。这些提案或类似提案很可能会包含在即将发布的版本中。

    将中间模型的信息存储为关系的元数据可能很诱人。但这样做会带来严重的限制,我强烈建议不要走这条路:

    1. JSON:API 规范不包括更改元数据。您需要引入自己的规范来创建或更新这些元数据。
    2. JSON:API 规范的客户端库不期望此类信息可用作关系的元数据。消费者很可能很难处理这些信息。
    3. 存储中间资源的信息会锁定您使用resource linkage 在资源文档中表达关系信息。您将无法使用related resource links。这些可能会引入严重的性能问题,因为资源链接需要始终在数据库中查找相关资源的 ID,而使用相关资源链接则不需要。

    【讨论】:

      猜你喜欢
      • 2017-09-21
      • 2014-09-17
      • 2017-05-28
      • 1970-01-01
      • 2013-05-31
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-29
      相关资源
      最近更新 更多