Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
node-jsonapi-serializer
Advanced tools
A Node.js framework agnostic library for serializing your data to JSON API
A Node.js framework agnostic library for serializing your data to JSON API (1.0 compliant).
$ npm install jsonapi-serializer
JSONAPISerializer(type, data, opts) serializes the data (can be an object or an array) following the rules defined in opts.
data
key inside the relationship. Default: false.// Sample data object
var data = [{
id: 1,
firstName: 'Sandro',
lastName: 'Munda'
},{
id: 2,
firstName: 'John',
lastName: 'Doe'
}];
var JSONAPISerializer = require('jsonapi-serializer').Serializer;
var users =new JSONAPISerializer('users', data, {
topLevelLinks: { self: 'http://localhost:3000/api/users' },
dataLinks: {
self: function (user) {
return 'http://localhost:3000/api/users/' + user.id
}
},
attributes: ['firstName', 'lastName']
});
// `users` here are JSON API compliant.
The result will be something like:
{
"links": {
"self": "http://localhost:3000/api/users"
},
"data": [{
"type": "users",
"id": "1",
"attributes": {
"first-name": "Sandro",
"last-name": "Munda"
},
"links": "http://localhost:3000/api/users/1"
}, {
"type": "users",
"id": "2",
"attributes": {
"first-name": "John",
"last-name": "Doe"
},
"links": "http://localhost:3000/api/users/2"
}]
}
### Nested resource
```javascript
var JSONAPISerializer = require('jsonapi-serializer');
var users = new JSONAPISerializer('users', data, { topLevelLinks: { self: 'http://localhost:3000/api/users' }, attributes: ['firstName', 'lastName', 'address'], address: { attributes: ['addressLine1', 'zipCode', 'city'] } });
// users
here are JSON API compliant.
The result will be something like:
```javascript
{
"links": {
"self": "http://localhost:3000/api/users"
},
"data": [{
"type": "users",
"id": "1",
"attributes": {
"first-name": "Sandro",
"last-name": "Munda",
"address": {
"address-line1": "630 Central Avenue",
"zip-code": 24012,
"city": "Roanoke"
}
}
}, {
"type": "users",
"id": "2",
"attributes": {
"first-name": "John",
"last-name": "Doe",
"address": {
"address-line1": "400 State Street",
"zip-code": 33702,
"city": "Saint Petersburg"
}
}
}]
}
### Compound document
var JSONAPISerializer = require('jsonapi-serializer');
var users = new JSONAPISerializer('users', data, {
topLevelLinks: { self: 'http://localhost:3000/api/users' },
attributes: ['firstName', 'lastName', 'books'],
books: {
ref: '_id',
attributes: ['title', 'isbn'],
relationshipLinks: {
"self": "http://example.com/relationships/books",
"related": "http://example.com/books"
},
relationshipMeta: {
count: function(user, book) {
return user.books.length;
},
},
includedLinks: {
self: function (dataSet, book) {
return 'http://example.com/books/' + book.id;
}
}
}
});
// `users` here are JSON API compliant.
The result will be something like:
{
"links": {
"self": "http://localhost:3000/api/users"
},
"data": [{
"type": "users",
"id": "1",
"attributes": {
"first-name": "Sandro",
"last-name": "Munda"
},
"relationships": {
"books": {
"data": [
{ "type": "books", "id": "1" },
{ "type": "books", "id": "2" }
],
"links": {
"self": "http://example.com/relationships/books",
"related": "http://example.com/books"
},
"meta": {
"count": 2
}
}
}
}, {
"type": "users",
"id": "2",
"attributes": {
"first-name": "John",
"last-name": "Doe"
},
"relationships": {
"books": {
"data": [
{ "type": "books", "id": "3" }
],
"links": {
"self": "http://example.com/relationships/books",
"related": "http://example.com/books"
},
"meta": {
"count": 1
}
}
}
}],
"included": [{
"type": "books",
"id": "1",
"attributes": {
"title": "La Vida Estilista",
"isbn": "9992266589"
},
"links": {
"self": "http://example.com/books/1"
}
}, {
"type": "books",
"id": "2",
"attributes": {
"title": "La Maria Cebra",
"isbn": "9992264446"
},
"links": {
"self": "http://example.com/books/2"
}
}, {
"type": "books",
"id": "3",
"attributes": {
"title": "El Salero Cangrejo",
"isbn": "9992209739"
},
"links": {
"self": "http://example.com/books/3"
}
}]
}
JSONAPIDeSerializer(collectionName, payload) deserializes a JSON API payload
(e.g req.body or res.body) into collectionName it can be either {}
or
an Object "Class".
JSON API Payload
var body = {
"data": {
"id": "1453732635522",
"attributes": {
"order-type": "subscription",
"production-state": "0",
"payment-state": "0",
"shipment-state": "0",
"created-at": null,
"ship-date": null,
"season": "WN16",
"box-status": "items choosen",
"has-add-ons": false
},
"relationships": {
"plan": {
"data": {
"type": "plans",
"id": "2-shirt"
}
},
"details": {
"data": [
{
"type": "order-details",
"id": "1453732637371"
}
]
},
"customer": {
"data": {
"type": "customers",
"id": "1453732635522"
}
}
},
"type": "orders"
}
}
var JSONAPIDeSerializer = require('jsonapi-serializer').DeSerializer;
var serialized = new JSONAPIDeSerializer({}, body);
Result
{
"orderType": "subscription",
"productionState": "0",
"paymentState": "0",
"shipmentState": "0",
"createdAt": null,
"shipDate": null,
"season": "WN16",
"boxStatus": "items choosen",
"hasAddOns": false,
"plan": {
"id": "2-shirt"
},
"details": [
{
"id": "1453732637371"
}
],
"customer": {
"id": "1453732635522"
},
"id": "1453732635522"
}
Example with Express Server and Mongoose
var express = require('express');
var bodyParser = require('body-parser');
var JSONAPIDeSerializer = require('jsonapi-serializer').DeSerializer;
var _ = require('lodash');
// parse application/json
app.use(bodyParser.json());
// parse application/vnd.api+json as json
app.use(bodyParser.json({
type: 'application/vnd.api+json'
}));
/**
* JSON API Content-Type HEADER
*/
app.use((req, res, next) => {
res.set('Content-Type', 'application/vnd.api+json');
next();
});
var orders = require('./lib/orders');
// JSON API deserializer as express middleware
app.use((req, res, next) => {
// If request Content-Type is plain JSON do not serialize
// If request does not have body (e.g) GET or req.body = {} do not serialize
// If request body is not JSON API compliant do not serialize (e.g) req.body is not empty but not inside data
if (req.headers['Content-Type'] === 'application/json' ||
_.isEmpty(req.body) ||
_.isEmpty(req.body.data)) {
return next();
}
var model = new JSONAPIDeSerializer({}, req.body);
// Only pick not (null or undenfined) attributes
model = _.pick(model, (attr) => {
return attr !== null && attr !== undefined;
});
req.model = model;
next();
});
// Resources
app.use('/orders', orders);
Normalize JSON API relationships into Mongoose relationships
var _ = require('lodash');
// relationships comes in { plan: { id: '1-shirt' } }
// but because we are using Mongoose, id doesn't allow us to use plain JS objects
// so we need to extract ids
function normalize(relationships) {
var normalizedData = {};
relationships = relationships || {};
Object.keys(relationships).forEach((k) => {
let key = _.camelCase(k);
let relationData;
if (_.isArray(relationships[k])) {
if (_.isEmpty(relationships[k])) {
relationData = [];
} else {
relationData = relationships[k].data;
}
} else {
relationData = relationships[k] ? relationships[k].data : null;
}
if (!relationData) {
return;
}
if (_.isArray(relationData)) {
normalizedData[key] = relationData.map((relationObject) => relationObject.id);
} else if (relationData.id) {
normalizedData[key] = relationData.id;
} else {
normalizedData[key] = null;
}
});
return normalizedData;
}
module.exports.normalize = normalize;
Order Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var OrderSchema = new Schema({
customer: { type: Schema.Types.ObjectId, ref: 'Customer' },
address: { type: Schema.Types.ObjectId, ref: 'Address'},
season: { type: String },
details: [{ type: Schema.Types.ObjectId, ref: 'OrderDetail' }],
createdAt: { type: Date, default: Date.now() },
updatedAt: { type: Date, default: Date.now() }
});
Order's Route
var Express = require('express');
var Order = require('ec-domain').Order;
var Serializer = require('../serializers');
var OrdersSerializer = require('../serializers/orders_serializer');
var app = new Express();
/**
* POST
*/
.post((req, res, next) => {
var newOrder = req.model; // => From Express Middleware
// Then normalize JSON API relationships
_.merge(newOrder, Serializer.normalize(req.body.data.relationships));
// Then create Order schema
return Order.create(newOrder).then((order) => {
debug('order created', order.id);
// On success serialize created order
const jsonapi = new OrdersSerializer(order.toObject()).serialize();
return res.status(201).send(jsonapi);
}, next);
});
module.exports = app;
FAQs
A Node.js framework agnostic library for serializing your data to JSON API
The npm package node-jsonapi-serializer receives a total of 0 weekly downloads. As such, node-jsonapi-serializer popularity was classified as not popular.
We found that node-jsonapi-serializer demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.