Skip to content

Instantly share code, notes, and snippets.

@tomdale
Last active December 21, 2015 03:29
Show Gist options
  • Save tomdale/6242743 to your computer and use it in GitHub Desktop.
Save tomdale/6242743 to your computer and use it in GitHub Desktop.
Notional API for new Ember Data adapter
App.Adapter = DS.Adapter.extend({
/*
Called when the store needs the data payload for a particular record. It
gets the type and ID and should return a promise that resolves to a JSON
payload that contains the record.
For example, this might be called like this:
findRecord(App.Person, "1")
And would return a promise that resolves to:
{
person: {
id: 1,
first_name: "Yehuda",
last_name: "Katz",
addresses: [{
id: 2,
city: "Portland",
state: "OR"
}],
spouse: 3
},
people: [{
id: 3,
first_name: "Leah",
last_name: "Silber",
addresses: [{
id: 2,
city: "Portland",
state: "OR"
}]
}]
}
*/
findRecord: function(type, id) {
// Given App.Person, toURL() -> "/person"
return $.getJSON(type.toURL() + "/" + id);
},
/*
If implemented, this method will be passed the same arguments as the `findRecord`
method, as well as the payload returned. Because the response from the
server may contain representations of *multiple* records (via embedding
and/or sideloading, as illustrated above), the job of the `extractFind`
method is to extract all of those representations and return them to the
store.
Given the above example, this method should return the following (note the
camelized keys).
{
people: [{
id: 1,
firstName: "Yehuda",
lastName: "Katz",
addresses: [2]
spouse: 1
}, {
id: 3,
firstName: "Leah",
lastName: "Silber",
addresses: [2]
}],
addresses: [{
id: 2,
city: "Portland",
state: "OR"
}]
}
*/
extractFind: function(type, id, payload) {
var extracted = {};
var people = [];
var addresses = [];
// Get all of the people into a single array
people = payload.people || [];
people.push(payload.person);
people = people.map(function(person) {
// Map embedded addresses into IDs and add them
// to the addresses array if they haven't been
// seen before.
person.addresses = person.addresses.map(function(address) {
if (!addresses.findProperty('id', address.id)) {
addresses.push(address);
}
return addresses.id;
});
// Transform e.g. first_name -> firstName
return this.camelizeKeys(person);
}, this);
return {
people: people,
addresses: addresses
}
},
/**
Similar to `findRecord`, `createRecord` is used to tell the adapter that
the store wants it to save a given record. It should return a promise that
resolves to a JSON payload that contains the current state of the record.
For example, the server may automatically generated `updated_at` and
`created_at` fields, which would be sent back in addition to any properties
that were sent in the initial POST.
In our case, our server might return a payload like this:
{
person: {
id: 5,
first_name: "Tom",
last_name: "Dale",
addresses: [{
id: 2,
city: "Portland",
state: "OR"
}],
spouse: null,
updated_at: "Thu Aug 15 2013 11:20:41 GMT-0700 (PDT)",
created_at: "Thu Aug 15 2013 11:20:41 GMT-0700 (PDT)"
}
}
*/
createRecord: function(type, id, record) {
return $.ajax({
type: 'POST',
url: type.toURL(),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(record.toJSON())
});
},
/**
Because our server returns a payload in the same format as when we ask for
an existing record, we can re-use our `extractFind()` method to pull apart
the response into its constituent records. If sideloaded or embedded records
have changed, they'll be automatically updated with their new values.
*/
extractCreate: function(type, id, payload) {
return this.extractFind(type, id, payload);
}
});
// to show how small this really is
App.Adapter = DS.Adapter.extend({
extractFind: function(type, id, payload) {
var extracted = {};
var people = [];
var addresses = [];
people = payload.people || [];
people.push(payload.person);
people = people.map(function(person) {
person.addresses = person.addresses.map(function(address) {
if (!addresses.findProperty('id', address.id)) {
addresses.push(address);
}
return addresses.id;
});
return this.camelizeKeys(person);
}, this);
return {
people: people,
addresses: addresses
}
},
createRecord: function(type, id, record) {
return $.ajax({
type: 'POST',
url: type.toURL(),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(record.toJSON())
});
},
extractCreate: function(type, id, payload) {
return this.extractFind(type, id, payload);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment