JSON API and translations with Ember Data

What’s the best JSON API architecture for easy usage with Ember Data, mobile SDKs, … and why knowing that each page can have a different number of translations?

The write interface, is currently made using option 2) inline.

Option 1) As Hash

{
  pages: [
    {
      id: 1,
      title: {
        en: "Title",
        fr: "Titre"
        ...
      }
    }
  ]
}

Option 2) Inline

{
  pages: [
    {
      id: 1,
      title_en: "Title",
      title_fr: "Titre"
      ...
    }
  ]
}

P.S: I’ve also posted this question on JSON API and translations with Ember Data - Stack Overflow but I’m not sure their’s a uniq / proper answer to this, it might lead to more discussion and best practice recommendations.

I think your first approach is generally better, but I’m not a big fan of embedding objects in data payloads. I would do something like this:

{
  pages: [
    {
      id: 1,
      title: 1
    }
  ]
}

{
    strings: [
        {
            id: 1,
            en: "Title",
            fr: "Titre"
        },{
            ...
        }
    ]
}

Thanks for your input @kylecoberly I don’t think flatting the translations as new object would make sense here. Each translation’s set is uniq to a page (they won’t be cases where you end up loading multiple time the same translations in multiple page) but also their’s no internal ID for this translations, giving IDs would imply a complete new model with all it’s CRUD actions on the server side which feels a bit overcomplicated I believe.

It would definitely mean a new model, new CRUD handlers, etc. I like this approach because it decouples the transitive dependency in having “French translation of title” tied to “page”. You may not want to reuse the strings now, but you might a year from now and have to rework your architecture.

In practice, the cost for reworking that architecture may be minimal, and this approach could definitely be overkill for your application- your call. If that’s the case, embedding objects is probably the best way to go.

In practice I can’t find any justification to share a translated title between to pages so will try to keep away from this idea.

After playing with both solutions, the Inlined version (2) appear to be really easy to work with in Ember, no issue with dirty tracking, same attribute name for reading and writing (which makes it easier to understand as well I believe), … Do you find some issues with this approach that make you prefer the Hash version (1) ?

Thanks a lot for your feedback on this, really appreciated.

If you wanted to go with Option 1) you can use a raw transform

var RawTransform = DS.Transform.extend({
  deserialize: function(serialized) {
    if (Ember.isNone(serialized)) {
      return {};
    } else {
      return serialized;
    }
  },
  serialize: function(deserialized) {
    if (Ember.isNone(deserialized)) {
      return {};
    } else {
      return deserialized;
    }
  }
});

Then in your model:

title: DS.attr('raw')

I try to avoid this when possible, but some times it adds more complexity than it’s worth to separate it out.