Jeffrey C
Jeffrey C

Reputation: 433

How to configure Ember to get data from multiple hosts in same model?

I have an Ember app, whenever it queries, I want it to send to 2 hosts. How do I do this?

Example:

Given 2 backend hosts: hosts=['host1-url', 'host2-url'], when I do this.get('store').findAll('post'),

It calls host1-url/posts and host2-url/posts, then concat the results together.

Upvotes: 0

Views: 92

Answers (1)

Jean-Philippe Roy
Jean-Philippe Roy

Reputation: 4812

In order to query a single model, you'll have to create a custom adapter for you model and implement your own findAll method. And that would look something like this. Keep in mind you would still have to modify it in order to handle HTTP failures and you'd have ensure that ids are unique across both endpoints or you'll lose some records in the process.

// adapters/post.js
import DS from 'ember-data';
import RSVP from 'rsvp';
import $ from 'jquery';
import { A } from '@ember/array';
import { computed } from '@ember/object';

export default DS.RESTAdapter.extend({
  hosts: computed(function () {
    return A(['http://www.host-1-url.com', 'http://www.host-2-url.com']);
  }),

  async findAll(store, type, sinceToken) {
    let query = { since: sinceToken };

    // Query both hosts
    let promises = this.get('hosts').map(async host => await $.getJSON(`${host}/api/posts`, query));

    // Get responses
    let responses = await RSVP.all(promises);

    // Fabricate a payload that contains all the posts
    let posts = await [].concat.apply([], responses.map(response => response.posts));
    return { posts: posts };
  }
});

If you want this code to run in your Ember app you'll need to add this to your ember-cli-build.js file in order to accommodate the async/await keywords:

'ember-cli-babel': {
  includePolyfill: true
}

Personally, I would go about it a different way.

I would create two models source1-post and source2-post, two adapters in order to specify their respective host and I would merge the two feeds when presenting the data to the user.

Either way, both approaches will yield the same end result.

Upvotes: 2

Related Questions