@swaggerexpert/json-api-merge
is a JSON:API specific redundant duplication algorithm for merging included resources into original data.
Get professionally supported @swaggerexpert/json-api-merge with Tidelift Subscription. |
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/