3

The examples here don't go nearly far enough in explaining how to produce a more complicated structure...

If I want to end up with something like:

{
  "data": {
    "type": "mobile_screens",
    "id": "1",
    "attributes": {
      "title": "Watch"
    },
    "relationships": {
      "mobile_screen_components": {
        "data": [
          {
            "id": "1_1",
            "type": "mobile_screen_components"
          },
          {
            "id": "1_2",
            "type": "mobile_screen_components"
          },
          ...
        ]
      }
    }
  },
  "included": [
    {
      "id": "1_1",
      "type": "mobile_screen_components",
      "attributes": {
        "title": "Featured Playlist",
        "display_type": "shelf"
      },
      "relationships": {
        "playlist": {
          "data": {
            "id": "938973798001",
            "type": "playlists"
          }
        }
      }
    },
    {
      "id": "938973798001",
      "type": "playlists",
      "relationships": {
        "videos": {
          "data": [
            {
              "id": "5536725488001",
              "type": "videos"
            },
            {
              "id": "5535943875001",
              "type": "videos"
            }
          ]
        }
      }
    },
    {
      "id": "5536725488001",
      "type": "videos",
      "attributes": {
        "duration": 78321,
        "live_stream": false,
        "thumbnail": {
          "width": 1280,
          "url":
            "http://xxx.jpg?pubId=694940094001",
          "height": 720
        },
        "last_published_date": "2017-08-09T18:26:04.899Z",
        "streams": [
          {
            "url":
              "http://xxx.m3u8",
            "mime_type": "MP4"
          }
        ],
        "last_modified_date": "2017-08-09T18:26:27.621Z",
        "description": "xxx",
        "fn__media_tags": [
          "weather",
          "personality"
        ],
        "created_date": "2017-08-09T18:23:16.830Z",
        "title": "NOAA predicts most active hurricane season since 2010",
        "fn__tve_authentication_required": false
      }
    },
    ...,
  ]
}

what is the most simple data structure and serializer I can set up?

I get stumped after something like:

const mobile_screen_components = responses.map((currentValue, index) => {
  id[`id_${index}`];
});
const dataSet = {
  id: 1,
  title: 'Watch',
  mobile_screen_components,
};
const ScreenSerializer = new JSONAPISerializer('mobile_screens', {
  attributes: ['title', 'mobile_screen_components'],
  mobile_screen_components: {
    ref: 'id',
  }
});

Which only gives me:

{
  "data": {
    "type": "mobile_screens",
    "id": "1",
    "attributes": { "title": "Watch" },
    "relationships": {
      "mobile-screen-components": {
        "data": [
          { "type": "mobile_screen_components", "id": "1_0" },
          { "type": "mobile_screen_components", "id": "1_1" },
          { "type": "mobile_screen_components", "id": "1_2" },
          { "type": "mobile_screen_components", "id": "1_3" },
          { "type": "mobile_screen_components", "id": "1_4" },
          { "type": "mobile_screen_components", "id": "1_5" }
        ]
      }
    }
  }
}

I have no idea how to get the "included" sibling to "data." etc.

Brian Burns
  • 20,575
  • 8
  • 83
  • 77
two7s_clash
  • 5,755
  • 1
  • 27
  • 44
  • I think you should boil down your question as much as you can. See https://stackoverflow.com/help/how-to-ask – Kamran Sep 01 '17 at 01:49
  • @kamran cut out some more of that initial JSON structure, but that's about as minimal of a representation as I can make... – two7s_clash Sep 01 '17 at 14:52
  • Although it wasn't immediately clear, this question is based on using https://github.com/SeyZ/jsonapi-serializer with the intent of building APIs using http://jsonapi.org/ spec. – Matt Lo Sep 03 '17 at 02:45
  • Sorry I don't get how is your initial data?, would you specify – Hosar Sep 03 '17 at 04:28

2 Answers2

3

So, the question is:

what is the most simple data structure and serializer I can set up?

Below is the simplest object that can be converted to JSON similar to JSON in the question using jsonapi-serializer:

let dataSet = {
  id: '1',
  title: 'Watch',
  mobile_screen_components: [
    {
      id: '1_1',
      title: 'Featured Playlists',
      display_type: 'shelf',
      playlists: {
        id: 938973798001,
        videos: [
          {
            id: 5536725488001,
            duration: 78321,
            live_stream: false
          },
          {
            id: 5535943875001,
            duration: 52621,
            live_stream: true
          }
        ]
      }
    }
  ]
};

To serialize this object to JSON API, I used the following code:

let json = new JSONAPISerializer('mobile_screen', {
  attributes: ['id', 'title', 'mobile_screen_components'],
  mobile_screen_components: {
    ref: 'id',
    attributes: ['id', 'title', 'display_type', 'playlists'],
    playlists: {
      ref: 'id',
      attributes: ['id', 'videos'],
      videos: {
        ref: 'id',
        attributes: ['id', 'duration', 'live_stream']
      }
    }
  }
}).serialize(dataSet);

console.log(JSON.stringify(json, null, 2));
  1. The first parameter of JSONAPISerializer constructor is the resource type.
  2. The second parameter is the serialization options.
  3. Each level of the options equals to the level of the nested object in serialized object.
  4. ref - if present, it's considered as a relationships.
  5. attributes - an array of attributes to show.
alexmac
  • 19,087
  • 7
  • 58
  • 69
1

Introduction

First of all we have to understand the JSON API document data structure

[0.1] Refering to the top level (object root keys) :

A document MUST contain at least one of the following top-level members:

data: the document’s “primary data” 
errors: an array of error objects   
meta: a meta object that contains non-standard meta-information.

A document MAY contain any of these top-level members:

jsonapi: an object describing the server’s implementation
links: a links object related to the primary data.
included: an array of resource objects that are related to the primary data and/or each other (“included resources”).

[0.2]

The document’s “primary data” is a representation of the resource or collection of resources targeted by a request.

Primary data MUST be either:

  1. a single resource identifier object, or null, for requests that target single resources
  2. an array of resource identifier objects, or an empty array ([]), for reqs. that target collections

Example

The following primary data is a single resource object:

{
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": {
      // ... this article's attributes
    },
    "relationships": {
      // ... this article's relationships
    }
  }
}

In the (jsonapi-serializer) documentation : Available serialization option (opts argument)

So in order to add the included (top-level member) I performed the following test :

var JsonApiSerializer = require('jsonapi-serializer').Serializer;
const DATASET = {
  id:23,title:'Lifestyle',slug:'lifestyle',
  subcategories: [
   {description:'Practices for becoming 31337.',id:1337,title:'Elite'},
   {description:'Practices for health.',id:69,title:'Vitality'}
  ]
}
const TEMPLATE = {
  topLevelLinks:{self:'http://example.com'},
  dataLinks:{self:function(collection){return 'http://example.com/'+collection.id}},
  attributes:['title','slug','subcategories'],
  subcategories:{ref:'id',attributes:['id','title','description']}
}
let SERIALIZER = new JsonApiSerializer('pratices', DATASET, TEMPLATE)
console.log(SERIALIZER)

With the following output :

{ links: { self: 'http://example.com' },
  included: 
   [ { type: 'subcategories', id: '1337', attributes: [Object] },
     { type: 'subcategories', id: '69', attributes: [Object] } ],
  data: 
   { type: 'pratices',
     id: '23',
     links: { self: 'http://example.com/23' },
     attributes: { title: 'Lifestyle', slug: 'lifestyle' },
     relationships: { subcategories: [Object] } } }

As you may observe, the included is correctly populated.


NOTE : If you need more help with your dataSet, edit your question with the original data.

EMX
  • 6,066
  • 1
  • 25
  • 32
  • That long bit of JSON (my first quoted "code") represents the data. Or at least how it needs to be output. – two7s_clash Sep 05 '17 at 14:02
  • @two7s_clash : you need to create a `TEMPLATE` that fits your data structure, we cannot really do that for you, since you haven't showed original data, just an output. The template for the parser is built based upon your original data to obtain the output you really want – EMX Sep 05 '17 at 17:28
  • the output data is the same as the input data, the former is just serialized in a specific way. As you can see from the above answers, my very question is about how to format the data as input to give me the form I want as output. totally doable. – two7s_clash Sep 06 '17 at 18:33