Many existing JSON APIs are not consistent between types. As JSON endpoints grew organically and were built by different engineers at different times, the style in which records are represented can vary wildly.
Historically, we have asked adapter authors to rely on the fact that the type of record is
provided to all adapter hooks (either by passing a type
argument, or by passing a record
whose constructor
can be used) to decide when to use different URLs or serializers.
While this approach works, it tends to lead to complicated and noisy code that is annoying to write:
find: function(store, type, id) {
if (type === App.Post) {
$.ajax('/enterprise_cms/v134uu5/db-legacy/posts_endpoint-v2/'+id, 'GET', {
success: function(json) {
store.load(type, json);
}
});
} else if (type === App.Comment) {
$.ajax('/comments/'+id, 'GET', {
success: function(json) {
store.load(type, json);
}
});
}
// ...more conditionals here
}
Users should be able to specify adapters and serializers on a per-type basis, to remove the need for these ugly, monolithic conditionals.
Now, instead of specifying a single adapter for the store, multiple adapters can be registered. Each adapter is associated with one or more types, like this:
// Types can be specified as either strings or classes
DS.Store.registerAdapter(['App.Post', 'App.Comment'], DS.Adapter.extend({
find: function(store, type, id) {
$.ajax(this.buildURL(type), 'GET', {
success: function(json) {
store.load(type, json);
}
});
}
}));
DS.Store.registerAdapter('App.LegacyModel', DS.Adapter.extend({
find: function(store, type, id) {
$.ajax('/crazy-larrys-java-api/iamondrugs/this-url_is&so-long?id='+id, 'GET', {
success: function(json) {
store.load(type, json);
}
});
}
}));
You can still specify a default adapter for the store by using the existing syntax:
App.Store = DS.Store.extend({
adapter: 'App.MyAdapter'
});
This default adapter will be used as a fallback if you try to load a record that does not have an adapter specified for its type.