Adjust Naming Conventions in Adapters and Serializers

Last reviewed in June 2019 with Ember Octane

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?

import DS from 'ember-data';
import { dasherize } from '@ember/string';

export default class ApplicationAdapter extends DS.RESTAdapter {
  pathForType(type) {
    return 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:

import DS from 'ember-data';

export default class ApplicationSerializer extends DS.JSONAPISerializer {
  modelNameFromPayloadKey(payloadKey) {
    if (payloadKey === "profile-data") {
      return payloadKey;
    } else {
      return super.modelNameFromPayloadKey(payloadKey);

The symmetrical function is also available: payloadKeyFromModelName.

Octane news & best practices, straight to your inbox?

Snacks is the best of Ember Octane in a highly digestible monthly newsletter. (No spam. EVER.)


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.

import DS from 'ember-data';
import { decamelize } from '@ember/string';

export default class ApplicationSerializer extends DS.JSONAPISerializer {
  keyForAttribute(key, method) {
    return 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.

String examples

String provides a handful of methods to convert casing:

camelize('publishing_house') // => publishingHouse
decamelize("createdAt") // => created_at
dasherize("blog_post") // => "blog-post"

Did you find this helpful?

Enjoyed this article? Join Snacks!

Snacks is the best of Ember Octane in a highly digestible monthly newsletter. (No spam. EVER.)