正确格式化 Ember 侧载 JSON API 数据的自定义序列化程序响应

Properly formatting Ember custom serializer response for sideloaded JSON API data

我想尝试为我的 Ember 应用提供 sideloaded data。我有一个 city 模型 hasMany fireStations。我将 hasMany 关系更改为具有 { async: false } 选项以配合侧载,因为数据将不再异步加载。

我使用自定义序列化程序,并且正在记录来自 normalize() 的响应。我的数据看起来像这样。

{
  "data": {
    "id": "3",
    "type": "city",
    "attributes": {
      "name": "Anytown USA"
    },
    "relationships": {
      "fireStations": {
        "data": [
          {
            "id": "17",
            "type": "fire-station"
          },
          {
            "id": "18",
            "type": "fire-station"
          }
        ]
      }
    }
  },
  "included": [
    {
      "id": "17",
      "type": "fire-station",
      "attributes": {
        "name": "North Side Fire Station"
      },
      "relationships": {}
    },
    {
      "id": "18",
      "type": "fire-station",
      "attributes": {
        "name": "East Side Fire Station"
      },
      "relationships": {}
    }
  ]
}

认为 我的旁加载数据格式正确。它似乎匹配 example in the guidesincluded 数组填充了我所有的旁加载数据,并且似乎都根据需要进行了格式化。

但是,我在我的应用程序中遇到了这个错误。

Assertion Failed: You looked up the 'fireStations' relationship on a 'city' with id 3 but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async ('DS.hasMany({ async: true })')

根据 JSON API 规范,我使用的格式似乎适合加载 compound documents.

In a compound document, all included resources MUST be represented as an array of resource objects in a top-level included member.

而且 links 似乎是可选的,所以我将它们排除在外应该没问题。

The optional links member within each resource object contains links related to the resource.

我不明白这是什么问题。我分叉了 ember-data locally and I do indeed see this assertion is triggered.

如果我手动遍历 has-many.js 中的 manyArray,我会看到每条记录都被标记为 isEmpty true

为什么 has-many 条记录返回 isEmpty === true?我可能做错了什么导致旁加载无法正常工作?

我能够创建 Ember Twiddle 来查找、重新创建和解决我的问题。

简短的回答是我的自定义序列化程序在规范化过程中丢失了 included。我混淆了 normalize() and normalizeResponse() 和从错误方法返回 included 之间的责任。

我试图在 normalize() 中的散列上设置 included 属性(这就是您在我上面的问题中看到的内容)。这种做法是完全错误的。

如果需要,

included 应该出现在 normalizeResponse() 的响应中。所以我(多余地)在 response() 中有 included,但在 normalizeResponse() 中实际需要的地方没有。

normalizeResponse (store, primaryModelClass, payload, id, requestType) {
  let { data, included } = this._super(...arguments);

  // Do some manipulation on `data` or `included`.

  // Oh no! We lost the `included` array!
  // This will cause an error
  // because we are saying the
  // relationship is not async, but we're
  // dropping the `included` data!
  return { data };

  // This is what we want, for this contrived example.
  // return { data, included };
}

如果需要返回included数组,应该从normalizeResponse()返回,而不是normalize()。对于查看 JSONAPISerializer in json-api.js 源代码的任何人来说,这应该是显而易见的,但我不知何故迷路了。

the JSONAPISerializer implementation for ember-data 2.17.0中,可以看到在normalizeResponse()调用的方法中documentHash上设置了included

我的序列化器做了很多定制,因为我的API非常不标准,我误解了这里的一些细节。此外,我认为尽管有文档,但在 each of the various normalize... API hooks 中理解应该做什么和不应该做什么有点困难。不过,我想如果我花更多的时间阅读它们,我可能会理解这一点。