docs/integrations/ember-and-json-api
Integrating with Ember and JSON API
Preparation
Note: This guide assumes that ember-cli
is used for your ember app.
The JSON API specification calls for hyphens for multi-word separators. ActiveModelSerializers uses underscores.
To solve this, in Ember, both the adapter and the serializer will need some modifications:
Server-Side Changes
there are multiple mimetypes for json that should all be parsed similarly, so
in config/initializers/mime_types.rb
:
api_mime_types = %W( application/vnd.api+json text/x-json application/json ) Mime::Type.unregister :json Mime::Type.register 'application/json', :json, api_mime_types
Adapter Changes
// app/adapters/application.js import DS from 'ember-data'; import ENV from "../config/environment"; export default DS.JSONAPIAdapter.extend({ namespace: 'api', // if your rails app is on a different port from your ember app // this can be helpful for development. // in production, the host for both rails and ember should be the same. host: ENV.host, // allows the multiword paths in urls to be underscored pathForType: function(type) { let underscored = Ember.String.underscore(type); return Ember.String.pluralize(underscored); }, // allows queries to be sent along with a findRecord // hopefully Ember / EmberData will soon have this built in // ember-data issue tracked here: // https://github.com/emberjs/data/issues/3596 urlForFindRecord(id, modelName, snapshot) { let url = this._super(...arguments); let query = Ember.get(snapshot, 'adapterOptions.query'); if(query) { url += '?' + Ember.$.param(query); } return url; } });
Serializer Changes
// app/serializers/application.js import Ember from 'ember'; import DS from 'ember-data'; var underscore = Ember.String.underscore; export default DS.JSONAPISerializer.extend({ keyForAttribute: function(attr) { return underscore(attr); }, keyForRelationship: function(rawKey) { return underscore(rawKey); } });
Including Nested Resources
Previously, store.find
and store.findRecord
did not allow specification of any query params.
The ActiveModelSerializers default for the include
parameter is to be nil
meaning that if any associations are defined in your serializer, only the id
and type
will be in the relationships
structure of the JSON API response.
For more on include
usage, see: The JSON API include examples
With the above modifications, you can execute code as below in order to include nested resources while doing a find query.
store.findRecord('post', postId, { adapterOptions: { query: { include: 'comments' } } });
will generate the path /posts/{postId}?include='comments'
So then in your controller, you’ll want to be sure to have something like:
render json: @post, include: params[:include]
If you want to use include
on a collection, you’d write something like this:
store.query('post', { include: 'comments' });
which will generate the path /posts?include='comments'