Series: Introduction to Ember Data 2.0

Ember Data 2.0-Overview of Customizing Adapters and Serializers

Published on Jan 15, 2016

The default Adapters and Serializers are great, but you aren’t stuck with them. There are two ways of customizing Adapters and Serializers.

The first way is extending the abstract base class (DS.Adapter or DS.Serializer), making sure to write the minimum set of methods.

The second way is extending a fully-functional Adapter or Serializer. The ones built into Ember Data have a rich set of methods that you can overwrite in order to tweak functionality.



You can extend DS.Serializer to build one from 'scratch'. Make sure to define the minimum set of 3 methods.

import DS from 'ember-data';

export default DS.Serializer.extend({
    serialize(snapshot, options){
        // code here

    normalizeResponse(store, primaryModelClass, payload, id, requestType){
        // code here

    normalize(modelClass, resourceHash){
        // optional
        // code here

You can do the same for DS.Adapter:

import DS from 'ember-data';

export default DS.Adapter.extend({
    findRecord(store, type, id, snapshot){},
    createRecord(store, type, snapshot){},
    updateRecord(store, type, snapshot){},
    deleteRecord(store, type, snapshot){},
    findAll(store, type, sinceToken){},
    query(store, type, query){},

    //optional, to increase speed
    findMany(store, type, ids, snapshots){}

These are the categories of methods you can overwrite on the JSONSerializer:

  • attrs
  • primaryKey
  • normalizeX
  • serializeX
  • keyForX
  • extractX
  • modelNameFromPayloadKey

There are a few additions on both JSONAPISerializer and RESTSerializer:

  • pushPayload
  • payloadKeyFromModelName

In addition, keyForPolymorphicType can be found on RESTSerializer.

These are the categories of methods you can overwrite on the RESTAdapter:

  • namespace
  • host
  • headers
  • buildUrl
  • urlForX
  • findX
  • (create/delete/update)Record
  • generateIdForRecord
  • groupRecordsForFindMany
  • handleResponse
  • is(Invalid/Success)
  • pathForType
  • query(X)
  • serialize
  • shouldReloadX
  • sortQueryParams


In the first part of our adapters and serializers series, we looked at how to use adapters and serializers, the basics of that. In this episode, we’re going to look at the basics of how to customize them for your specific use.

So one way we can do that is to start from scratch, and not really from scratch. We’re starting from the DS.Serializer and DS.Adapter abstract base class. So to extend those, there are certain minimum level that we need to define for the serializer, the serializer method, and the normalizeResponse method. And we can also do the normalize method, but that’s optional.

For the adapter, there are a few more that we need to do, findRecord, createRecord, updateRecord, deleteRecord, findAll, and query, and we can do findMany to increase the speed. And remember as we said from last time, these are not the findRecord and createRecord and so on that you find on the store. These are instead finding the URL that we’ll use to contact the server when we’re doing certain actions.

So doing these from scratch, from the abstract base class, is good if you have a really unusual API. But for most of the time, we want to start with something a little bit more familiar, and so we can use the RESTAdapter or the JSONAPIAdapter, and then either the JSONSerializer, the RESTSerializer, or the JSONAPISerializer. And those are fairly complicated in their internal workings but they provide a good hierarchy of things to change.

So we’ll take the JSONSerializer. Here are all the methods that you can change, and for each of these you’re changing a small aspect of how it changes the data. Here are the different categories of methods. So here I’ve narrowed it down, so for example serializeX stands for serialize, serializeAttribute, serializeBelongsTo. So each of these determines how a certain type of thing is serialized. So serializeBelongsTo shows us how to serialize a belongsTo. And I’ll go into more details about a lot of these when we’re going over the serializer specifically.

So the takeaway from this slide is that each method is a leverage point that strategically interacts with other methods, and they’ve smartly divided it up so it’s easy to tell where to put what.

Of course the other ones aren’t exactly like the JSONSerializer. They’re mostly the same but the API is changed a little bit. So here are the methods that have been added in the REST and JSONAPI serializer.

So let’s look at the RESTAdapter as well. It has a few more categories, but the basic idea is the same. They interact and they’re divided up so that you can tell what each one is doing and you know which one to replace if you have something to change. If you have a different URL for getting the hasMany, then you’ll overwrite findHasMany. And you can leave everything else the same and it’ll work just like you expect it to.

What are the differences between the RESTAdapter and the JSONAPIAdapter? They are exactly the same in terms of their API, in terms of the things that you can overwrite. Of course the URL they’re spitting out looks quite a bit different.

So let’s go over quickly what we learned today. We learned that to create a serializer from scratch, you had to create the serialize and normalizeResponse methods on it, and extend from DS.Serializer. To start an adapter from scratch, you had to do these six methods, but you can also extend from several other types of adapters and serializers, and this is recommended for all but the weirdest adapters and serializers.

So JSONSerializer, these are the methods that you can change, and they’re a little bit different in the REST and JSONAPI serializers. And for the RESTAdapter, these are the methods that you can change, that you can overwrite. And the RESTAdapter and JSONAPIAdapter have the exact same methods that you can change.

In our next episode, we’re going to be digging deeper into adapters. I hope to see you then.

Introduction to Ember Data 2.0

Subscribe to our mailing list