我一直在调查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商店?
答案 0 :(得分:8)
据我所知,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)
}
}
}