Adjust Naming Conventions in Adapters and Serializers

Programming languages adopt different naming conventions. In Javascript, we are used to separate multiple-word attributes in camelCase whereas Ruby or Python prefer snake_case with underscores.

Backends may expose API endpoints and attribute names in JSON that are not what Ember expects.

How can we fix these casing discrepancies?

Customizing endpoint casing

As we saw earlier endpoints constitute the location of a resource and therefore must be customized in an Adapter.

A reader once had this problem:

When I do a “this.findAll(‘profile-data’)” with a model, adapter, and serializer set for ‘profile-data’, the “findAll” gets converted into a GET request to “/api/profileData”…

What change is necessary to hit the correct endpoint instead of the “camelized” version?

export default ApplicationAdapter.extend({
  pathForType(type) {
    return Ember.String.dasherize(type);
  }
});

Dasherizing the type (from profileData to profile-data) in pathForType!

For a complete URL customization have a look at the urlFor* methods.

Customizing payload casing

We know that adjustments to resource content belong in the Serializer.

The JSON API standard dictates that types in plural – but Ember works internally with models in singular form. The JSONAPISerializer takes this into consideration.

The payload of our previous example now contains a type profile-data. By default, Ember will singularize it to profile-datum, which in turn will throw an error as that model does not exist. This is not the most common case, but how do we override it?

Using modelNameFromPayloadKey:

export default JSONAPISerializer.extend({
  modelNameFromPayloadKey(payloadKey) {
    if (payloadKey === "profile-data") {
      return payloadKey;
    } else {
      return this._super(payloadKey);
    }
  }
});

The symmetrical function is also available: payloadKeyFromModelName.

Attributes

Many Rails projects include the created_at and updated_at attributes that we might want to use in our frontend.

Issues may arise with these snake_cased attributes not properly converting to camelCase. The fix is very easy anyway. We must override keyForAttribute, which converts an attribute name in our model to a key in our JSON.

export default JSONAPISerializer.extend({
  keyForAttribute(key, method) {
    return Ember.String.decamelize(key);
  }
});

This means that an attribute createdAt in our model will be mapped to created_at.

Similarly, keyForRelationship converts a relationship name to its key in JSON payload.

Ember.String examples

Ember.String provides a handful of methods to convert casing:

Ember.String.camelize('publishing_house') // => publishingHouse
Ember.String.decamelize("createdAt") // => created_at
Ember.String.dasherize("blog_post") // => "blog-post"
Ember.String.singularize("artists") // => "artist"

Enjoyed this article? Don't miss my next one!

Leave me your e-mail for content that will help you master Ember:

Do you want to master Ember fast?

Leave me your e-mail for helpful updates delivered straight to your inbox.

(A few e-mails per month. No BS. Unsubscribe anytime!)