jsonapi-serializer
jsonapi-serializer copied to clipboard
3.6.6 breaks deep relations
3.6.6 does not include relations deeper than the third level anymore. This worked in 3.6.5.
Expected result
- profiles
- layouts-profiles
- grid
- elements-layouts-profiles
- elements
- icons
- actions-elements
- actions
- events
- elements
- layouts-profiles
Actual result
- profiles
- layouts-profiles
- grid
- elements-layouts-profiles
- elements
- layouts-profiles
Data
{
"data":{
"type":"profiles",
"id":"23",
"attributes":{
"name":"Apotheker",
"created":"2019-11-19T13:16:36+00:00",
"modified":"2019-11-19T13:16:36+00:00"
},
"relationships":{
"layouts-profiles":{
"data":[
{
"type":"layouts-profiles",
"id":"21"
}
],
"links":{
"self":"\/apiv1\/layouts-profiles?profile-id=23"
}
}
},
"links":{
"self":"\/apiv1\/profiles\/23"
}
},
"included":[
{
"type":"icons",
"id":"9",
"attributes":{
"icon":"exclamation"
},
"links":{
"self":"\/apiv1\/icons\/9"
}
},
{
"type":"actions",
"id":"15",
"attributes":{
"action":"nextPriorityTicketInLine"
},
"links":{
"self":"\/apiv1\/actions\/15"
}
},
{
"type":"events",
"id":"1",
"attributes":{
"event":"mouseclickleft"
},
"links":{
"self":"\/apiv1\/events\/1"
}
},
{
"type":"actions-elements",
"id":"10",
"relationships":{
"action":{
"data":{
"type":"actions",
"id":"15"
},
"links":{
"self":"\/apiv1\/actions\/15"
}
},
"event":{
"data":{
"type":"events",
"id":"1"
},
"links":{
"self":"\/apiv1\/events\/1"
}
}
},
"links":{
"self":"\/apiv1\/actions-elements\/10"
}
},
{
"type":"events",
"id":"11",
"attributes":{
"event":"totalWaitingPriorityTickets"
},
"links":{
"self":"\/apiv1\/events\/11"
}
},
{
"type":"actions-elements",
"id":"11",
"relationships":{
"event":{
"data":{
"type":"events",
"id":"11"
},
"links":{
"self":"\/apiv1\/events\/11"
}
}
},
"links":{
"self":"\/apiv1\/actions-elements\/11"
}
},
{
"type":"elements",
"id":"2",
"attributes":{
"color":"f3a91f",
"content":null,
"content-color":"FFFFFF",
"row-start":2,
"col-start":0,
"row-end":2,
"col-end":4,
"is-rounded":0,
"is-dynamic":0
},
"relationships":{
"icon":{
"data":{
"type":"icons",
"id":"9"
},
"links":{
"self":"\/apiv1\/icons\/9"
}
},
"actions-elements":{
"data":[
{
"type":"actions-elements",
"id":"10"
},
{
"type":"actions-elements",
"id":"11"
}
],
"links":{
"self":"\/apiv1\/actions-elements?element-id=2"
}
}
},
"links":{
"self":"\/apiv1\/elements\/2"
}
},
{
"type":"elements-layouts-profiles",
"id":"170",
"relationships":{
"element":{
"data":{
"type":"elements",
"id":"2"
},
"links":{
"self":"\/apiv1\/elements\/2"
}
}
},
"links":{
"self":"\/apiv1\/elements-layouts-profiles\/170"
}
},
{
"type":"grids",
"id":"1",
"attributes":{
"width":484,
"height":112,
"row-count":6,
"col-count":12
},
"links":{
"self":"\/apiv1\/grids\/1"
}
},
{
"type":"layouts-profiles",
"id":"21",
"attributes":{
"zoom":1
},
"relationships":{
"elements-layouts-profiles":{
"data":[
{
"type":"elements-layouts-profiles",
"id":"170"
}
],
"links":{
"self":"\/apiv1\/elements-layouts-profiles?layout-profile-id=21"
}
},
"grid":{
"data":{
"type":"grids",
"id":"1"
},
"links":{
"self":"\/apiv1\/grids\/1"
}
}
},
"links":{
"self":"\/apiv1\/layouts-profiles\/21"
}
}
]
}
I have hit the same issue, and it appears to be a problem with how the code is detecting recursive relationships. If any of the parents have types that are a substring of the child type they will be detected as a recursive relation e.g. from your example because elements-layouts-profiles contains the string elements it won't keep parsing relations.
To work around this, in deserializer utils I have updated the check to look at type and id instead of just type when detecting a recursion.
...
function findIncluded(relationshipData, ancestry) {
...
if (included) {
// To prevent circular references, check if the record type
// has already been processed in this thread
if (ancestry.indexOf(included.type + included.id) > -1) {
...
up
up
I have hit the same issue, and it appears to be a problem with how the code is detecting recursive relationships. If any of the parents have types that are a substring of the child type they will be detected as a recursive relation e.g. from your example because elements-layouts-profiles contains the string elements it won't keep parsing relations.
To work around this, in deserializer utils I have updated the check to look at type and id instead of just type when detecting a recursion.
... function findIncluded(relationshipData, ancestry) { ... if (included) { // To prevent circular references, check if the record type // has already been processed in this thread if (ancestry.indexOf(included.type + included.id) > -1) { ...
I noticed I never replied to this, but still thanks @danielpigott.
We distribute this package onto our servers automatically so for now we're still on 3.6.5 since the issue doesn't occur there. It would be nice if this issue could be fixed in a future version so we can use the newest package.
So support for this library has been down. I've been recently going around the other serializers checking for people who are looking for a better serializer. Over the past few days I've designed a resource-recursive, typescript/javascript library for serializing the entire JSON:API spec. You might want to check it out if this library doesn't fix the recursion :)
@danielpigott @ev8dev @kln @Roriz So I have been going around looking for those who are struggling to find a proper JSONAPI serializer.
Over the past few days I've designed a resource-recursive, typescript/javascript library for serializing the entire JSON:API spec. Our API is far more fluent (and obvious) than the one here (and every other serializer I have seen/used). If this serializer doesn't fit your need, you might want to check it out :) Development is active.
If you are in particular struggling with issues such as links, resource relationships, and deep recursion (essentially any of the complicated parts of the JSON:API spec), I strongly recommend moving to our library.
{TS:JAPI}: https://github.com/jun-sheaf/ts-japi