Comments (11)
@wesselvdv, sorry for having breaking something... I agree with you that json-api-serializer
must also follow the rule you mention.
To clarify all cases:
1. If relationship is present and is null it should output with data: null
const JSONAPISerializer = require('json-api-serializer');
const Serializer = new JSONAPISerializer();
// Schools type
Serializer.register('schools', {
relationships: {
students: {
type: 'students',
links: {
self: '/students'
}
}
}
});
// Students type
Serializer.register('students', {
relationships: {
grades: {
type: 'grades',
links: {
self: '/grades'
}
}
}
});
Serializer.register('grades');
// Input data for schools
const input = {
"id": "1",
"name": "School Name",
"students": {
id: 1,
},
"grades": null
};
const output = Serializer.serialize('schools', input);
console.log(JSON.stringify(output));
Output should have data: null
for grades relationship:
{
"jsonapi": {
"version": "1.0"
},
"data": {
"type": "schools",
"id": "1",
"attributes": {
"name": "School Name"
},
"relationships": {
"students": {
"links": {
"self": "/students"
},
"data": {
"type": "students",
"id": "1"
}
}
}
},
"included": [
{
"type": "students",
"id": "1",
"attributes": {},
"relationships": {
"grades": {
"links": {
"self": "/grades"
},
"data": null
}
}
}
]
}
2. Considering I revert to data:undefined
if relationship is missing and it have at least one of the following links
or meta
property, it should output with data: undefined
const JSONAPISerializer = require('json-api-serializer');
const Serializer = new JSONAPISerializer();
// Schools type
Serializer.register('schools', {
relationships: {
students: {
type: 'students',
links: {
self: '/students'
}
}
}
});
// Students type
Serializer.register('students', {
relationships: {
grades: {
type: 'grades',
links: {
self: '/grades'
}
}
}
});
Serializer.register('grades');
// Input data for schools
const input = {
"id": "1",
"name": "School Name",
"students": {
id: 1,
}
};
const output = Serializer.serialize('schools', input);
console.log(JSON.stringify(output));
Output should not have data for grades relationship:
{
"jsonapi": {
"version": "1.0"
},
"data": {
"type": "schools",
"id": "1",
"attributes": {
"name": "School Name"
},
"relationships": {
"students": {
"links": {
"self": "/students"
},
"data": {
"type": "students",
"id": "1"
}
}
}
},
"included": [
{
"type": "students",
"id": "1",
"attributes": {},
"relationships": {
"grades": {
"links": {
"self": "/grades"
}
}
}
}
]
}
3. Considering I revert to data: undefined
If relationship is missing and NOT have at least one of the following links
or meta
property
const JSONAPISerializer = require('json-api-serializer');
const Serializer = new JSONAPISerializer();
// Schools type
Serializer.register('schools', {
relationships: {
students: {
type: 'students',
links: {
self: '/students'
}
}
}
});
// Students type
Serializer.register('students', {
relationships: {
grades: {
type: 'grades'
}
}
});
Serializer.register('grades');
// Input data for schools
const input = {
"id": "1",
"name": "School Name",
"students": {
id: 1,
}
};
Output will have empty object for grades relationship
{
"jsonapi": {
"version": "1.0"
},
"data": {
"type": "schools",
"id": "1",
"attributes": {
"name": "School Name"
},
"relationships": {
"students": {
"links": {
"self": "/students"
},
"data": {
"type": "students",
"id": "1"
}
}
}
},
"included": [
{
"type": "students",
"id": "1",
"attributes": {},
"relationships": {
"grades": {}
}
}
]
}
This case is not clear regarding the spec. I don't think "relationships": { "grades": {} }
" is a valid output, because it break the following rule:
relationship object” MUST contain at least one of the following:
- links: ...
- data: ...
- meta: ...
Is grades
relationship object should be filtered out from relationships
object in such case ?
Is grades
relationship object should have at least data
with null
?
@Mattii any ideas ?
from json-api-serializer.
@danivek I agree with the first two cases. Those appear to correspond to the json:api spec, and will make sure that the behaviour introduced by #38 is reverted.
Is grades relationship object should be filtered out from relationships object in such case ?
I wouldn't introduce this behaviour, this will cause a lot of confusion if objects just magically start disappearing.
Is grades relationship object should have at least data with null ?
I wouldn't do this either, this will cause the same situation as we have now, if I understand you correctly.
I suggest to introduce the following behaviour if a defined relationship is missing in an object that's serialised:
- If json-api-serializer can deduce the links object, or if it has been defined by the user in the type definition, and the relationships object is missing.
- Include the links object, make sure data is undefined, and if applicable include meta.
- If json-api-serializer can NOT deduce the links object, the relationships object is missing and no meta has been defined.
- Throw an exception stating that no spec compliant json:api object can be created.
- If json-api-serializer can NOT deduce the links object, the relationships object is missing, but meta data has been defined.
- Include the meta object and make sure data & links are undefined.
Unless I am missing something, the above should make sure that json-api-serializer always creates objects that are compliant.
from json-api-serializer.
@danivek thanks for the quick fix!!
from json-api-serializer.
@danivek I am seeing results that contradicts the second case in your previous comment.
I registered a type with about 15 relationships.
I fetched data without including any relationships, the resulting json includes all 15 relationships as
{
data: null
}
I would expect that if my data does not have any relationships defined, it should not attempt to serialize them even if they are registered with my type.
from json-api-serializer.
@danivek, thoughts?
from json-api-serializer.
@alechirsch, I think it breaks JSON:API specification https://jsonapi.org/format/#document-resource-object-linkage
Resource linkage MUST be represented as one of the following:
null for empty to-one relationships.
an empty array ([]) for empty to-many relationships.
What your input data looks like ?
from json-api-serializer.
According to this, it should NOT include related resources that were not requested
https://jsonapi.org/format/#fetching-includes
If an endpoint supports the include parameter and a client supplies it, the server MUST NOT include unrequested resource objects in the included section of the compound document.
I think #35 might be related to this.
In my case, I am requesting 1 relationship in the include
part of the my query. The data fetches one relationship and then it serializes ALL relationships that are registered with that type, even though the user does not request them.
from json-api-serializer.
What your input data looks like ?
json-api-serializer
tries to detect if a relationship has been populated or not by checking if it is a plain object. In this case, it tries to serialize the relation and set it in included
, otherwise it considers that it is an array of identifier or simply an identifier and set type
and id
in the relationship
data of a resource.
from json-api-serializer.
Here is an example of what I am talking about:
it('should not serialize relationships that were not provided', function(done) {
const Serializer = new JSONAPISerializer();
Serializer.register('people', {});
Serializer.register('article', {
relationships: {
author: {
type: 'people'
}
}
});
const data = {
id: '1',
title: 'Nice article'
};
const serialized = Serializer.serialize('article', data);
console.log(serialized);
expect(serialized.data).to.have.property('id');
expect(serialized.data.attributes).to.have.property('title');
expect(serialized.data.relationships).to.not.have.property('author');
done();
});
This produces:
{
jsonapi: { version: '1.0' },
meta: undefined,
links: undefined,
data: { type: 'article',
id: '1',
attributes: { title: 'Nice article' },
relationships: { author: { data: null } },
meta: undefined,
links: undefined
},
included: undefined
}
If data has an empty object called author
, then I would expect the above to be the result.
I expected this as the result
{
jsonapi: { version: '1.0' },
meta: undefined,
links: undefined,
data: { type: 'article',
id: '1',
attributes: { title: 'Nice article' },
relationships: {},
meta: undefined,
links: undefined
},
included: undefined
}
Also this statement mentions empty
relationships, not necessarily undefined relationships:
Resource linkage MUST be represented as one of the following:
null for empty to-one relationships.
an empty array ([]) for empty to-many relationships.
from json-api-serializer.
I would expect the code to be like this, it still produces null or empty array relationships IF the relationships are defined as empty in the data object provided.
// Line 627
if (
serializeRelationship.data !== undefined ||
serializeRelationship.links !== undefined ||
serializeRelationship.meta !== undefined
) {
// Convert case
relationship = options.convertCase
? this._convertCase(relationship, options.convertCase)
: relationship;
serializedRelationships[relationship] = serializeRelationship;
}
As opposed to this:
if (
serializeRelationship.data === undefined &&
serializeRelationship.links === undefined &&
serializeRelationship.meta === undefined
) {
serializeRelationship = {
data: null
};
}
// Convert case
relationship = options.convertCase
? this._convertCase(relationship, options.convertCase)
: relationship;
serializedRelationships[relationship] = serializeRelationship;
from json-api-serializer.
@alechirsch You're right, regarding the spec there's no reason for a missing relationship to be serialized as null
from json-api-serializer.
Related Issues (20)
- ObjectID (mongodb) should be serialized with .toString() and not treated as an object HOT 2
- Support extracting error class names into the 'title' field of JSON API errors HOT 1
- Error when try to deserialise an included relationship with `alternativeKey` HOT 3
- ErrorMaximum call stack size exceeded if `included` has cross references
- Would you be interested in a conversion to Typescript? HOT 2
- Error instance serialization missing properties HOT 1
- ValidationError: beforeSerialize is not allowed HOT 2
- Incorrectly deserializing relationship when alternativeKey is set from default and relationship data is not in the included array HOT 2
- Case conversion breaks on non-alphanumeric strings
- Unintended object in attributes HOT 2
- Is there an option to remove undefined properties? HOT 1
- The result after serialize will not have `included` if the input doesn't have attributes HOT 5
- Error thrown when relationship is not registered HOT 5
- Having no attributes in the relation data does not add relation to included array
- Use a cache for converting to snake/camel/kebab case HOT 1
- bug: When installed in Angular project, it throws error since it is searching for `fs` HOT 3
- Relationships do not work with ES2015 classes
- bug: Duplicated models from includes are removed from response HOT 1
- Support serialization of only meta HOT 2
- Support for relationship data serialization? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from json-api-serializer.