Package Exports
- json-api-serializer
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (json-api-serializer) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
json-api-serializer
A Node.js framework agnostic library for serializing your data to JSON API compliant responses (a specification for building APIs in JSON).
Why another library for serializing data to JSON API ?
Simply because others libraries are not as flexible as i need.
Installation
npm install --save json-api-serializerDocumentation
Register
var JSONAPISerializer = require('json-api-serializer');
var Serializer = new JSONAPISerializer();
Serializer.register(type, options);Serialization options :
- id (optional): The attributes to use as the reference. Default = 'id'.
- blacklist (optional): An array of blacklisted attributes. Default = [].
- whitelist (optional): An array of whitelisted attributes. Default = [].
- links (optional): An object or a function that describes the links inside data. (If it is an object values can be string or function).
- topLevelMeta (optional): An object or a function that describes the top-level meta. (If it is an object values can be string or function).
- topLevelLinks (optional): An object or a function that describes the top-level links. (If it is an object values can be string or function).
- relationships (optional): An object defining some relationships
- relationship: The property in data to use as a relationship
- type: The type to use for serializing the relationship (type need to be register)
- alternativeKey (optional): An alternative key to use if relationship key not exist (example: 'author_id' as an alternative key for 'author' relationship). See issue #12.
- schema (optional): A custom schema for serializing the relationship. If no schema define, it use the default one.
- links (optional): An object or a function that describes the links for the relationship. (If it is an object values can be string or function).
- relationship: The property in data to use as a relationship
- convertCase (optional): Case conversion for serializing data. Value can be :
kebab-case,snake_case,camelCase
Deserialization options :
- unconvertCase (optional): Case conversion for deserializing data. Value can be :
kebab-case,snake_case,camelCase - blacklistOnDeserialize (optional): An array of blacklisted attributes. Default = [].
- whitelistOnDeserialize (optional): An array of whitelisted attributes. Default = [].
Usage
input data (can be an object or an array of objects)
// Data
var data = [{
id: "1",
title: "JSON API paints my bikeshed!",
body: "The shortest article. Ever.",
created: "2015-05-22T14:56:29.000Z",
updated: "2015-05-22T14:56:28.000Z",
author: {
id: "1",
firstName: "Kaley",
lastName: "Maggio",
email: "Kaley-Maggio@example.com",
age: "80",
gender: "male"
},
tags: ["1", "2"],
photos: ["ed70cf44-9a34-4878-84e6-0c0e4a450cfe", "24ba3666-a593-498c-9f5d-55a4ee08c72e", "f386492d-df61-4573-b4e3-54f6f5d08acf"],
comments: [{
_id: "1",
body: "First !",
created: "2015-08-14T18:42:16.475Z"
}, {
_id: "2",
body: "I Like !",
created: "2015-09-14T18:42:12.475Z"
}, {
_id: "3",
body: "Awesome",
created: "2015-09-15T18:42:12.475Z"
}]
}]Register
Register your resources types :
var JSONAPISerializer = require('json-api-serializer');
var Serializer = new JSONAPISerializer();
// Register 'article' type
Serializer.register('article', {
id: 'id', // The attributes to use as the reference. Default = 'id'.
blacklist: ['updated'], // An array of blacklisted attributes. Default = []
links: { // An object or a function that describes links.
self: function(data) { // Can be a function or a string value ex: { self: '/articles/1'}
return '/articles/' + data.id;
}
},
relationships: { // An object defining some relationships.
author: {
type: 'people', // The type of the resource
links: function(data) { // An object or a function that describes Relationships links
return {
self: '/articles/' + data.id + '/relationships/author',
related: '/articles/' + data.id + '/author'
}
},
},
tags: {
type: 'tag'
},
photos: {
type: 'photo'
},
comments: {
type: 'comment',
schema: 'only-body' // A custom schema
}
},
topLevelMeta: function(extraOptions) { // An object or a function that describes top level meta.
return {
count: extraOptions.count,
total: extraOptions.total
}
},
topLevelLinks: { // An object or a function that describes top level links.
self: '/articles' // Can be a function (with extra options argument) or a string value
}
});
// Register 'people' type
Serializer.register('people', {
id: 'id',
links: {
self: function(data) {
return '/peoples/' + data.id;
}
}
});
// Register 'tag' type
Serializer.register('tag', {
id: 'id',
});
// Register 'photo' type
Serializer.register('photo', {
id: 'id',
});
// Register 'comment' type with a custom schema
Serializer.register('comment', 'only-body', {
id: '_id',
});Serialize
Serialize it with the corresponding resource type, data and optional extra options :
// Synchronously (blocking)
const result = Serializer.serialize('article', data, {count: 2});
// Asynchronously (non-blocking)
Serializer.serializeAsync('article', data, {count: 2})
.then((result) => {
...
});The output data will be :
{
"jsonapi": {
"version": "1.0"
},
"meta": {
"count": 2
},
"links": {
"self": "/articles"
},
"data": [{
"type": "article",
"id": "1",
"attributes": {
"title": "JSON API paints my bikeshed!",
"body": "The shortest article. Ever.",
"created": "2015-05-22T14:56:29.000Z"
},
"relationships": {
"author": {
"data": {
"type": "people",
"id": "1"
},
"links": {
"self": "/articles/1/relationships/author",
"related": "/articles/1/author"
}
},
"tags": {
"data": [{
"type": "tag",
"id": "1"
}, {
"type": "tag",
"id": "2"
}]
},
"photos": {
"data": [{
"type": "photo",
"id": "ed70cf44-9a34-4878-84e6-0c0e4a450cfe"
}, {
"type": "photo",
"id": "24ba3666-a593-498c-9f5d-55a4ee08c72e"
}, {
"type": "photo",
"id": "f386492d-df61-4573-b4e3-54f6f5d08acf"
}]
},
"comments": {
"data": [{
"type": "comment",
"id": "1"
}, {
"type": "comment",
"id": "2"
}, {
"type": "comment",
"id": "3"
}]
}
},
"links": {
"self": "/articles/1"
}
}],
"included": [{
"type": "people",
"id": "1",
"attributes": {
"firstName": "Kaley",
"lastName": "Maggio",
"email": "Kaley-Maggio@example.com",
"age": "80",
"gender": "male"
},
"links": {
"self": "/peoples/1"
}
}, {
"type": "comment",
"id": "1",
"attributes": {
"body": "First !"
}
}, {
"type": "comment",
"id": "2",
"attributes": {
"body": "I Like !"
}
}, {
"type": "comment",
"id": "3",
"attributes": {
"body": "Awesome"
}
}]
}Some others examples are available in tests folders
Deserialize
input data (can be an simple object or an array of objects)
var data = {
data: {
type: 'article',
id: '1',
attributes: {
title: 'JSON API paints my bikeshed!',
body: 'The shortest article. Ever.',
created: '2015-05-22T14:56:29.000Z'
},
relationships: {
author: {
data: {
type: 'people',
id: '1'
}
},
comments: {
data: [{
type: 'comment',
id: '1'
}, {
type: 'comment',
id: '2'
}]
}
}
}
};
Serializer.deserialize('article', data);{
"id": "1",
"title": "JSON API paints my bikeshed!",
"body": "The shortest article. Ever.",
"created": "2015-05-22T14:56:29.000Z",
"author": "1",
"comments": [
"1",
"2"
]
}Custom schemas
It is possible to define multiple custom schemas for a resource type :
Serializer.register(type, 'customSchema', options);Then you can apply this schema on the primary data when serialize or deserialize :
Serializer.serialize('article', data, 'customSchema', {count: 2});
Serializer.serializeAsync('article', data, 'customSchema', {count: 2});
Serializer.deserialize('article', jsonapiData, 'customSchema');Or if you want to apply this schema on a relationship data, define this schema on relationships options with the key schema :
Example :
relationships: {
comments: {
type: 'comment'
schema: 'customSchema'
}
}Requirements
json-api-serializer only use ECMAScript 2015 (ES6) features supported natively by Node.js 4 and above (ECMAScript 2015 (ES6) | Node.js). Make sure that you have Node.js 4+ or above.