Skip to content

Commit 9e7fec9

Browse files
stefanvanherwijnendanivek
authored andcommitted
Deserialize function for relationships (#68)
Closes #65
1 parent 17b85e0 commit 9e7fec9

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ Serializer.register(type, options);
5252
* **meta** (optional): Describes meta that contains non-standard meta-information about the relationship. It can be:
5353
* An _object_ (values can be string or function).
5454
* A _function_ with one argument `function(data) { ... }` or with two arguments `function(data, extraData) { ... }`
55+
* **deserialize** (optional): Describes the function which should be used to deserialize a related property which is not included in the JSON:API document. It should be:
56+
* A _function_ with one argument `function(data) { ... }`which defines the format to which a relation should be deserialized. By default, the ID of the related object is returned, which would be equal to `function(data) {return data.id}`. See [issue #65](https://github.com/danivek/json-api-serializer/issues/65).
5557
* **convertCase** (optional): Case conversion for serializing data. Value can be : `kebab-case`, `snake_case`, `camelCase`
5658

5759
**Deserialization options:**

lib/JSONAPISerializer.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ module.exports = class JSONAPISerializer {
6161
schema: joi.string().default('default'),
6262
links: joi.alternatives([joi.func(), joi.object()]).default({}),
6363
meta: joi.alternatives([joi.func(), joi.object()]).default({}),
64+
deserialize: joi.func(),
6465
})).default({}),
6566
topLevelLinks: joi.alternatives([joi.func(), joi.object()]).default({}),
6667
topLevelMeta: joi.alternatives([joi.func(), joi.object()]).default({}),
@@ -487,21 +488,27 @@ module.exports = class JSONAPISerializer {
487488
if (resourceOpts.relationships[relationshipKey] && resourceOpts.relationships[relationshipKey].alternativeKey) {
488489
relationshipKey = resourceOpts.relationships[relationshipKey].alternativeKey;
489490
}
491+
const deserializeFunction = (relationshipData) => {
492+
if (resourceOpts.relationships[relationshipKey] && resourceOpts.relationships[relationshipProperty].deserialize) {
493+
return resourceOpts.relationships[relationshipProperty].deserialize(relationshipData);
494+
}
495+
return relationshipData.id;
496+
};
490497

491498
if (relationship.data !== undefined) {
492499
if (Array.isArray(relationship.data)) {
493500
// Array data
494501
_set(deserializedData, relationshipKey, relationship.data.map(d => (included
495502
? this.deserializeIncluded(d.type, d.id, resourceOpts.relationships[relationshipProperty], included)
496-
: d.id)));
503+
: deserializeFunction(d))));
497504
} else if (relationship.data === null) {
498505
// null data
499506
_set(deserializedData, relationshipKey, null);
500507
} else {
501508
// Object data
502509
_set(deserializedData, relationshipKey, included
503510
? this.deserializeIncluded(relationship.data.type, relationship.data.id, resourceOpts.relationships[relationshipProperty], included)
504-
: relationship.data.id);
511+
: deserializeFunction(relationship.data));
505512
}
506513
}
507514
});

test/unit/JSONAPISerializer.test.js

+37
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,43 @@ describe('JSONAPISerializer', function() {
15201520
done();
15211521
});
15221522

1523+
it('should deserialize with \'deserialize\' option as a function', function(done) {
1524+
const Serializer = new JSONAPISerializer();
1525+
Serializer.register('articles', {
1526+
relationships: {
1527+
author: {
1528+
type: 'people',
1529+
deserialize: (data) => ({id: data.id, type: data.type})
1530+
}
1531+
}
1532+
});
1533+
1534+
const data = {
1535+
data: {
1536+
type: 'article',
1537+
id: '1',
1538+
attributes: {
1539+
title: 'JSON API paints my bikeshed!',
1540+
body: 'The shortest article. Ever.',
1541+
created: '2015-05-22T14:56:29.000Z'
1542+
},
1543+
relationships: {
1544+
author: {
1545+
data: {
1546+
type: 'people',
1547+
id: '1'
1548+
}
1549+
}
1550+
}
1551+
}
1552+
};
1553+
1554+
const deserializedData = Serializer.deserialize('articles', data);
1555+
expect(deserializedData.author).to.have.property('id');
1556+
expect(deserializedData.author).to.have.property('type');
1557+
done();
1558+
})
1559+
15231560
it('should deserialize with \'unconvertCase\' options', function(done) {
15241561
const Serializer = new JSONAPISerializer();
15251562
Serializer.register('articles', {

0 commit comments

Comments
 (0)