Class DS.JSONAPISerializer

Module: ember-data
Since: v1.13.0

Ember Data 2.0 Serializer:

In Ember Data a Serializer is used to serialize and deserialize records when they are transferred in and out of an external source. This process involves normalizing property names, transforming attribute values and serializing relationships.

JSONAPISerializer supports the http://jsonapi.org/ spec and is the serializer recommended by Ember Data.

This serializer normalizes a JSON API payload that looks like:

app/models/player.js
1
2
3
4
5
6
7
8
import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  skill: DS.attr('string'),
  gamesPlayed: DS.attr('number'),
  club: DS.belongsTo('club')
});
app/models/club.js
1
2
3
4
5
6
7
import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  location: DS.attr('string'),
  players: DS.hasMany('player')
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  {
    "data": [
      {
        "attributes": {
          "name": "Benfica",
          "location": "Portugal"
        },
        "id": "1",
        "relationships": {
          "players": {
            "data": [
              {
                "id": "3",
                "type": "players"
              }
            ]
          }
        },
        "type": "clubs"
      }
    ],
    "included": [
      {
        "attributes": {
          "name": "Eusebio Silva Ferreira",
          "skill": "Rocket shot",
          "games-played": 431
        },
        "id": "3",
        "relationships": {
          "club": {
            "data": {
              "id": "1",
              "type": "clubs"
            }
          }
        },
        "type": "players"
      }
    ]
  }

to the format that the Ember Data store expects.

Customizing meta

Since a JSON API Document can have meta defined in multiple locations you can use the specific serializer hooks if you need to customize the meta.

One scenario would be to camelCase the meta keys of your payload. The example below shows how this could be done using normalizeArrayResponse and extractRelationship.

app/serializers/application.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export default JSONAPISerializer.extend({
  normalizeArrayResponse(store, primaryModelClass, payload, id, requestType) {
    let normalizedDocument = this._super(...arguments);

    // Customize document meta
    normalizedDocument.meta = camelCaseKeys(normalizedDocument.meta);

    return normalizedDocument;
  },

  extractRelationship(relationshipHash) {
    let normalizedRelationship = this._super(...arguments);

    // Customize relationship meta
    normalizedRelationship.meta = camelCaseKeys(normalizedRelationship.meta);

    return normalizedRelationship;
  }
});

Show:

Module: ember-data

The attrs object can be used to declare a simple mapping between property names on DS.Model records and payload keys in the serialized JSON object representing the record. An object with the property key can also be used to designate the attribute's key on the response payload.

Example

app/models/person.js
1
2
3
4
5
6
7
8
import DS from 'ember-data';

export default DS.Model.extend({
  firstName: DS.attr('string'),
  lastName: DS.attr('string'),
  occupation: DS.attr('string'),
  admin: DS.attr('boolean')
});
app/serializers/person.js
1
2
3
4
5
6
7
8
import DS from 'ember-data';

export default DS.JSONSerializer.extend({
  attrs: {
    admin: 'is_admin',
    occupation: { key: 'career' }
  }
});

You can also remove attributes and relationships by setting the serialize key to false in your mapping object.

Example

app/serializers/person.js
1
2
3
4
5
6
7
8
import DS from 'ember-data';

export default DS.JSONSerializer.extend({
  attrs: {
    admin: { serialize: false },
    occupation: { key: 'career' }
  }
});

When serialized:

1
2
3
4
5
{
  "firstName": "Harry",
  "lastName": "Houdini",
  "career": "magician"
}

Note that the admin is now not included in the payload.

Setting serialize to true enforces serialization for hasMany relationships even if it's neither a many-to-many nor many-to-none relationship.

Module: ember-data

The primaryKey is used when serializing and deserializing data. Ember Data always uses the id property to store the id of the record. The external source may not always follow this convention. In these cases it is useful to override the primaryKey property to match the primaryKey of your external store.

Example

app/serializers/application.js
1
2
3
4
5
import DS from 'ember-data';

export default DS.JSONSerializer.extend({
  primaryKey: '_id'
});
Module: ember-data

The store property is the application's store that contains all records. It can be used to look up serializers for other model types that may be nested inside the payload response.

Example:

1
2
3
4
5
6
7
Serializer.extend({
  extractRelationship(relationshipModelName, relationshipHash) {
    var modelClass = this.store.modelFor(relationshipModelName);
    var relationshipSerializer = this.store.serializerFor(relationshipModelName);
    return relationshipSerializer.normalize(modelClass, relationshipHash);
  }
});