Use custom URL with Ember Data

I have a backend that follows the JSON API specification.

In my Ember app, I do something like this:

model() {
  return this.store.query('category', { filter: { forum: 'main' } });
}

This works well and the request sent to the server is GET /categories?filter[forum]=main. My app gets all the categories from the forum with ID main.

Now, instead of the previous request, I would like to make a GET /forums/main/categories from the model. How can this be done in Ember with Ember Data?

Here’s something I tried with Ember AJAX:

ajax: Ember.inject.service(),

model() {
  return Ember.RSVP.hash({
    categories: this.get('ajax').request('/forums/main/categories'),
  });
}

The request works and the correct data is returned from the server. But Ember Data just doesn’t know about it and I can’t use the model in my template. How can I make Ember AJAX work with Ember Data?

The Ember AJAX GitHub page proposes to write something like that:

import DS from 'ember-data';
import AjaxServiceSupport from 'ember-ajax/mixins/ajax-support';

export default DS.JSONAPIAdapter.extend(AjaxServiceSupport);

But it doesn’t seem to change anything.

Any help would be appreciated. Thank you.

If i understood correctly you’re looking for an adapter for your category model:

You can then configure your endpoint to point to ‘forums/main/categories’

The category.js adapter is placed in app/adapters and would propably look like:

import DS from ‘ember-data’;

export default DS.RESTAdapter.extend({ namespace: 'forums/main });

I have read about adapters, but I don’t think that’s this is what I’m looking for. (I might be wrong)

The request GET /forum/main/relationships is a valid JSON API request. Why can’t I use it with Ember Data?

Thank you for your example, but main is an ID and in your code example, you hard code the ID in the adapter. Somewhere else in my app, I might want to GET /forums/abc123/categories.

You may use ember-data-url-templates - npm

You’re right in that you’re wrong :wink: Adapters are what you are looking for. I certainly wouldn’t use ajax like that!

Override the query method in your categories adapter. I haven’t tested it, but something along these lines:

query: function query(store, type, query) {
  let main = query.filter.forum;
  let url = `${this.get('host')}/forums/${main}/categories;
  return this.ajax(url, 'GET', { data: query });
}

Depending on your whole URL structure you may want to override other parameters. If you’d like to understand what’s an adapter and why I suggested the former, have a look at Fit Any Backend Into Ember with Custom Adapters & Serializers - Ember Igniter

I don’t think you need to.

Can’t you just do the following?

/forums/main/categories.js this will make a request to GET /categories endpoint model() { return this.store.findAll(‘category’); }

How about if you want the end model name to be different?

Currently, the model name is category for example. And adding a namespace: "forums/main"will make the API endpoint forums/main/categories.

How can you get the url forums/main/foo , where foo is any name you pick for the URL?

Thanks

You’d probably want to use the adapter’s pathForType method.

1 Like

Thank you. That works :smiley: