DS.RESTAdapter and Singular Resources

I can do no better than quote the Rails Routing Guide for the background to my query:

Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like /profile to always show the profile of the currently logged in user.

As far as I can see, when using the REST adapter, the only options for accessing such a singular resource are (a) include an id value in the request URL and have the server ignore it, or (b) sub-class the adapter and over-ride buildURL.

Neither of these seems ideal. Is there a better way that I haven’t understood? And if not, should there not be a built-in option for what must be a common case?

1 Like

With ember-auth you have a this.auth variable so on your profile page you could do something like

App.ProfileRoute = Ember.Route.extend({
  model: function() {
      this.store.find('user', @auth.get('userId'));
   }
 }

If not using ember-auth you could also use (if using rails) a gem like gon to pass down the current user’s id into javascript

One solution I’ve found isn’t also ideal, but is more convenient.

You can edit the ember inflector to make the plural of a word to be the same word. Therefore, when you perform astore.find("profile") you are calling to the index action of the wallet resource.

Anyway, I’ve reached the conclusion that none of those ideas is the ember way of doing thing. You will be more happy if you just pass an id, like if it where a plural resource. Just pass the ID of the user, even if its not really necesary. Just ignore it. Anyway, sending an ID is always usefull if you want to perform any kind of caching in a higher level, ourside your application.

It’s possible I’m being too precious about this, but it feels wrong to be including an id value in requests if the server is going to ignore it. There is an established pattern for interacting with resources in the case when there is only a single resource that a client can legitimately access, and I’d like to see the REST adapter implement it.

I’d hesitate to say that the Ember Way, or even the Ember Data REST Adapter Way, is wrong, but as far as I can tell, this case isn’t handled, and your reply seems to confirm this.

In the particular case of user profiles, there is a practical disadvantage to using URLs with id values in them. A naive or incompetent programmer working on the server end might just plug in something like inherited-resources with the defaults and end up using the id to retrieve the record, thus allowing a malicious user to edit other people’s profiles. (I seem to remember that Diaspora did something like this when it was first released.)

User profiles aren’t the only case to consider, though. For instance, another classic example is when a project has a single manager, so you want URLs like /project/1/manager not /project/1/manager/99. Of course, I’m talking here about the URLs provided by the API, which Ember Data talks to, not the URLs in the Ember application that the end user sees.

I don’t know enough about the internals of Ember Data to feel competent to make a specific proposal. Does it make sense to have a singletonModel class? Or is the idea of a singular resource specifically a REST thing, which should be dealt with (in some unspecified way) by the adapter?

2 Likes

Did by any chance the support for singularized resources get added to EmberData during the last 6 months? Or, maybe, any best practices emerged? I agree with macavon, passing an id seems wrong.

3 Likes

This may work in few cases: ember-api-actions - npm