Side Loading

Ember Data supports “sideloading” of data; i.e., indicating that data should be retrieved (along with the primary data requested) so as to help multiple related HTTP requests.

A common use case is sideloading associated models. For example, each Shop has many groceries, so we can include all related groceries in /shops response:

GET /shops
{
  "shops": [
    {
      "id": "14",
      "groceries": ["98", "99", "112"]
    }
  ]
}

When the groceries association is accessed, Ember Data will issue:

GET /groceries?ids[]=98&ids[]=99&ids[]=112
{
  "groceries": [
    { "id": "98",      "provider": "14", "type": "shop" },
    { "id": "99",  "provider": "14", "type": "shop" },
    { "id": "112", "provider": "14", "type": "shop" }
  ]
}

However, if we instead return associated Groceries in /shops endpoint, Ember Data won’t need to issue another request:

GET /shops
{
  "shops": [
    {
      "id": "14",
      "groceries": ["98", "99", "112"]
    }
  ],

  "groceries": [
    { "id": "98",  "provider": "14", "type": "shop" },
    { "id": "99",  "provider": "14", "type": "shop" },
    { "id": "112", "provider": "14", "type": "shop" }
  ]
}

Links

Ember Data accepts links in place of association IDs. When an association specified as a link is accessed, Ember Data will issue a GET request to that link in order to get the associated records.

For example, we could return a link for a groceries association:

  GET /shops
  {
    "shops": [
    {
      "id": "14",
      "links": {
      "groceries": "/shops/14/groceries"
    }
  }
 ]
}

And Ember Data would then issue a request to /shops/14/groceries:

GET /shops/14/groceries
{
  "groceries": [
    { "id": "98",  "provider": "14", "type": "shop" },
    { "id": "99",  "provider": "14", "type": "shop" },
    { "id": "112", "provider": "14", "type": "shop" }
  ]
}

Keep in mind that you still need to represent the association in the data; links just suggest a new HTTP request and won’t affect associations.

Active Model Serializer and Adapter

Arguably, ActiveModelSerializer and ActiveModelAdapter are more used in practice than RESTSerializer and RESTAdapter. In particular, when the backend uses Ruby on Rails and the ActiveModel::Serializers gem, the best option is to use ActiveModelSerializer and ActiveModelAdapter, since they support ActiveModel::Serializers out of the box.

Fortunately, though, the usage differences between ActiveModelSerializer/ActiveModelAdapter and RESTSerializer/RESTAdapter are quite limited; namely:

  1. ActiveModelSerializer will use snake_case field names while RESTSerializer requires camelCased field names.
  2. ActiveModelAdapter issues requests to snake_case API methods while RESTSerializer issues to camelCased API methods.
  3. ActiveModelSerializer expects association related field names to end in _id or _ids while RESTSerializer expects association related field names to be the same as the association field.

Regardless of the Adapter and Serializer choice, Ember Data models will be exactly the same. Only JSON representation and API endpoints will be different.