npmversion npm Node CI Dependabot enabled try on RunKit Tidelift
@swaggerexpert/json-api-merge
is a JSON:API specific redundant duplication algorithm for merging included resources into original data.
npm i @swaggerexpert/json-api-merge
or
yarn add @swaggerexpert/json-api-merge
const jsonApiData = { data: { id: 1, type: 'resource', attributes: { name: 'Resource name', }, relationships: { related: { data: { id: 2, type: 'related_resource', }, }, }, }, included: [ { id: 2, type: 'related_resource', attributes: { name: 'Related resource name', }, }, ], };
import jsonApiMerge from '@swaggerexpert/json-api-merge' jsonApiMerge(jsonApiData.included, jsonApiData.data)
const jsonApiMerge = require('@swaggerexpert/json-api-merge'); jsonApiMerge(jsonApiData.included, jsonApiData.data);
Result would be following data structure.
{ id: 1, type: 'resource', attributes: { name: 'Resource name', }, relationships: { related: { data: { id: 2, type: 'related_resource', attributes: { name: 'Related resource name', }, }, }, }, }
The library can also process data in list format and can transform this:
{ data: [ { id: 1, type: 'resource', attributes: { name: 'Resource name', }, relationships: { related: { data: { id: 2, type: 'related_resource', }, }, }, } ], included: [ { id: 2, type: 'related_resource', attributes: { name: 'Related resource name', }, }, ], }
into this:
[ { id: 1, type: 'resource', attributes: { name: 'Resource name', }, relationships: { related: { data: { id: 2, type: 'related_resource', attributes: { name: 'Related resource name', }, }, }, }, } ]
To reduce the number of HTTP requests, servers MAY allow responses that include related resources along with the requested primary resources. Such responses are called "compound documents".
const jsonApiData = { data: [ { type: 'articles', id: '1', attributes: { title: 'JSON:API paints my bikeshed!', }, links: { self: 'http://example.com/articles/1', }, relationships: { author: { links: { self: 'http://example.com/articles/1/relationships/author', related: 'http://example.com/articles/1/author', }, data: { type: 'people', id: '9' }, }, comments: { links: { self: 'http://example.com/articles/1/relationships/comments', related: 'http://example.com/articles/1/comments', }, data: [ { type: 'comments', id: '5' }, { type: 'comments', id: '12' }, ], }, }, }, ], included: [ { type: 'people', id: '9', attributes: { firstName: 'Dan', lastName: 'Gebhardt', twitter: 'dgeb', }, links: { self: 'http://example.com/people/9', }, }, { type: 'comments', id: '5', attributes: { body: 'First!', }, relationships: { author: { data: { type: 'people', id: '2' }, }, }, links: { self: 'http://example.com/comments/5', }, }, { type: 'comments', id: '12', attributes: { body: 'I like XML better', }, relationships: { author: { data: { type: 'people', id: '9' }, }, }, links: { self: 'http://example.com/comments/12', }, }, ], };
Compound documents can achieve full linkage with the following trick:
const included = jsonApiMerge(jsonApiData.included, jsonApiData.included); jsonApiMerge(included, jsonApiData.data);
This operation will generate following compound document with full linkage:
[ { type: 'articles', id: '1', attributes: { title: 'JSON:API paints my bikeshed!', }, links: { self: 'http://example.com/articles/1', }, relationships: { author: { links: { self: 'http://example.com/articles/1/relationships/author', related: 'http://example.com/articles/1/author', }, data: { type: 'people', id: '9', attributes: { firstName: 'Dan', lastName: 'Gebhardt', twitter: 'dgeb', }, links: { self: 'http://example.com/people/9', }, }, }, comments: { links: { self: 'http://example.com/articles/1/relationships/comments', related: 'http://example.com/articles/1/comments', }, data: [ { type: 'comments', id: '5', attributes: { body: 'First!', }, relationships: { author: { data: { type: 'people', id: '2', }, }, }, links: { self: 'http://example.com/comments/5', }, }, { type: 'comments', id: '12', attributes: { body: 'I like XML better', }, relationships: { author: { data: { type: 'people', id: '9', attributes: { firstName: 'Dan', lastName: 'Gebhardt', twitter: 'dgeb', }, links: { self: 'http://example.com/people/9', }, }, }, }, links: { self: 'http://example.com/comments/12', }, }, ], }, }, }, ];
I was looking for a simple way how to merge the included
into data
without compromising data
structures. All other libraries that I tested were opinionated about how the resulting merge should look like.
This library has no opinion and simply merged the included
into data
. It does nothing else.
If you want to contribute to this project, please consult the CONTRIBUTING.md guidelines.
Obtaining project copy
$ git clone https://github.com/swaggerexpert/json-api-merge $ npm i
Running tests
$ npm run test
Running tests in browser
$ npm run test:web
Running linter
We're using eslint and airbnb codestyle rules with prettier integrated as an eslint plugin.
$ npm run lint
Although @swaggerexpert/json-api-merge is written in ES2019, we also support Typescript. When @swaggerexpert/json-api-merge gets imported into a Typescript project, typings are automatically imported and used.
char0n (Vladimír Gorej)
contact@swaggerexpert.com
https://swaggerexport.com/