haydn / json-api-store

An isomorphic JavaScript library that acts as an in memory data store for JSON API data.
http://particlesystem.com/json-api-store
MIT License
73 stars 5 forks source link

Attribute type and datatype collision #57

Open Redsandro opened 7 years ago

Redsandro commented 7 years ago

The id and type of a resource object are merged into the attributes. If attributes contains a property type or id, the resource object's identifiers are overwritten, and can no longer be identified.

Any resource object with a relationship to another resource who's type identifier is overwritten by a type attribute will result in an error when pushed to the store:

{
  "data": {
    "type": "components",
    "id": "1104",
    "attributes": {
      "detail": "Component for regulating power",
      "type": "power_regulators"
    },
    "relationships": {
      "product": {
        "data": {
          "type": "products",
          "id": "361"
        }
      }
    }
  },
  "included": [
    {
      "type": "products",
      "id": "361",
      "attributes": {
        "stock": 43
      },
      "relationships": {
        "component": {
          "data": {
            "type": "components",
            "id": "1104"
          }
        }
      }
    }
  ]
}
store.js:624 Uncaught TypeError: Cannot read property '_names' of undefined
   at Store._addInverseRelationship (http://adap.dev/json-api-store/dist/store.dev.js:13284:76)
   at http://adap.dev/json-api-store/dist/store.dev.js:13272:21
   at Array.forEach (native)
   at Store._addField (http://adap.dev/json-api-store/dist/store.dev.js:13271:20)
   at http://adap.dev/json-api-store/dist/store.dev.js:12770:24
   at Array.forEach (native)
   at http://adap.dev/json-api-store/dist/store.dev.js:12768:37
   at Store.add (http://adap.dev/json-api-store/dist/store.dev.js:12779:13)
   at http://adap.dev/json-api-store/dist/store.dev.js:13172:25
   at Array.forEach (native)

Deprecating usage of type as an attribute fixes this problem. However, the JSON API spec does allow for using this keyword as an attribute. It is afaik not reserved. That's why the data is in separate objects in the first place.

Attributes and identifiers should be kept separate. I guess a semi-quick fix would be to prepend them with an underscore (_) internally. However, many JSON API servers are backed by MongoDB, which uses _id natively, and apps configure adapters to use _id for relationships. As a workaround, the identifiers could be prepended with two underscores in stead, so this:

{
  "data": {
    "type": "components",
    "id": "1104",
    "attributes": {
      "detail": "Component for regulating power",
      "type": "power_regulators"
    }
  }
}

Will result in the following store item:

{
  "__id": "1104",
  "__type": "components",
  "type": "power_regulators",
  "detail": "Component for regulating power",
}