【问题标题】:Normalizing JSON API Standard v1规范化 JSON API 标准 v1
【发布时间】:2016-02-04 09:02:16
【问题描述】:

我一直在研究 normalizr 以扁平化格式为 standard JSON API format 的 JSON API 数据。谁能指出我这样做的一些例子?我特别关注如何处理资源对象关系的 normalizr 模式(由 JSON API 标准定义)。在 JSON API 标准中,资源对象中定义了一个“关系”属性,然后是每组相关对象的属性。以下是 JSON API 格式的单个产品类别与两个相关产品的示例:

{
  "jsonapi": {
    "version": "1.0"
  },
  "meta": {
    "time": "0.006"
  },
  "data": [
    {
      "type": "category",
      "id": "6",
      "attributes": {
        "name": "Odwalla"
      },
      "meta": {
        "product_count": "0"
      },
      "relationships": {
        "product": {
          "data": [
            {
              "type": "product",
              "id": "4785"
            },
            {
              "type": "product",
              "id": "4786"
            }
          ]
        }
      }
    }
  ],
  "included": [
    {
      "type": "product",
      "id": "4786",
      "attributes": {
        "name": "Strawberry & Banana Odwalla",
        "description": null,
        "price": "3.19",
        "upc": ""
      }
    },
    {
      "type": "product",
      "id": "4785",
      "attributes": {
        "name": "Blueberry Odwalla",
        "description": null,
        "price": "3.19",
        "upc": ""
      }
    }
  ]
}

该类别中包含的产品列在 data.relationships.product.data 下,并且这些产品对象包含在包含的数组中。我相信有很多方法可以使这一点正常化;对于 Flux/Redux 商店来说,最有效和最友好的方式是什么?

【问题讨论】:

    标签: json api flux redux


    【解决方案1】:

    据我了解 json:api 提供标准化数据。相关数据不直接嵌套在主资源中,而是included — 请参阅此Compound Documents 和Fetching Includes。 normalizr 并不适用于这种数据结构,但如果这是您的意图,您可以轻松构建一些可以为您提供与 normalizr 相同的结果的东西。由于 json:api 是一个非常严格的标准,因此非常适合使用。这就是我尝试实现这一目标的方式,从 normalizr 库中获得了很多“灵感”……

    import { reduce, append } from 'ramda'
    
    export default function normalize({data, included}) {
      let bag = {}
      const result = visit(data, bag)
      visit(included, bag)
    
      return {
        entities: bag,
        result
      }
    }
    
    function visitIterable(obj, bag) {
      return reduce((acc, item) => {
        const entityId = visitEntity(item, bag)
        return append(entityId, acc)
      }, [], obj)
    }
    
    function visitEntity(obj, bag) {
      const entityKey = obj.type
      const entityId = obj.id
    
      if (!bag.hasOwnProperty(entityKey)) {
        bag[entityKey] = {}
      }
    
      bag[entityKey][entityId] = obj
      return entityId
    }
    
    function visit(obj, bag) {
      if (Array.isArray(obj)) {
        return {
          list: visitIterable(obj, bag)
        }
      } else if (typeof obj === 'object') {
        return {
          item: visitEntity(obj, bag)
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 1970-01-01
      • 2012-04-04
      • 2020-08-03
      • 2021-04-26
      • 2022-07-12
      • 2018-09-06
      相关资源
      最近更新 更多