Configure backend url with ember data and fastboot

TLDR:

when using fastboot, how should one let ember data know about the backend location? preferably not hard coding urls into the ember app

long story:

If I deploy a fastboot app server and an ember app which uses the ember-data rest adapter and do not configure any host within the adapter, the fastboot server tries to reach the backend on its own port. For instance, if fastboot is running on port 4000, I can see via tcpdump, that it tries to connect to the backend at localhost:4000. So, this seems to get us nowhere…

Now, there are two options: configure a host with the adapter, which specifies a public uri to the backend (using the same uri from the browser as from the fastboot server). Or we could use a public uri from the browser and stay within the private network when the request originates from the fastboot server.

As it seems at very least unnecessary to leave the private network, I was trying to specify a different host variable in the rest adapter depending wether we are running in fastboot mode or not. While this generally worked, I quickly noticed that this approach broke addons like the ember storefront fastboot adapter, as it uses the whole uri when deciding if it could server data from the shoebox - and now being unable to use data from the fastboot shoebox in the browser.

As all these points seem like pretty basic things when setting up fastboot, either a lot more people should have similar issues, or probably I am missing something pretty fundamental or doing something the wrong way? Unfortunately I wasn’t able to find anything within the docs or via employing a search engine, so how are you handling these issues?

We’ve run into something similar, I think your best bet is to have a custom host computed on your adapter.

import { inject as service } from '@ember/service';
import config from 'my-app/config/environment';
import DS from 'ember-data';
import { computed } from '@ember/object';

export default DS.JSONAPIAdapter.extend({

  fastboot: service(),

  host: computed('fastboot.isFastBoot', function() {
    let fastboot = this.fastboot;

    if (fastboot.isFastBoot && config.environment === 'production') {
      // Force any production fastboot request made by Ember data to use the internal network
      return `https://internal.backend`;
    }
  })
});

If you don’t want to hardcode the host in the adapter, you could set it in config/environment using an ENV variable at build time.

Also, I’m the maintainer of storefront and it sounds like there’s a bug somewhere! Is the issue you’re facing with the FastBoot adapter that is breaks when the hostname is different between FastBoot and the client rendered app?

1 Like

This is what we do, however I agree it would be faster to stay in private network. One thing that occurs to me—could you configure your fastboot server’s /etc/hosts (or dns daemon?) to resolve api.mypublicserver.com to internal.address:5000? I’m not exactly sure all the tradeoffs involved with this approach but at first glance it seems like they might be favorable…

thanks for your reply. yes, this is exactly the issue I am seeing. When data is added to the shoebox on the fastboot server, it gets stored under a key which contains the full url and such the internal domain. When the app is rendered inside the browser, storefront is unable to retrieve data from the shoebox as it is unaware of the internal url which was used in fastboot mode.

I was able to set different hosts using an env var, so I think it’s just the storefront issue and everything should be fine :slight_smile:

it turned out that my env vars were not solving the issues as I expected.

I expected that when I would launch the fastboot server, it would pick up the env var, which would be propageted through the app and would end up in something like config.myVar. However, I think the env var is only picked up at build time within the ember environment config and such my approach only worked in dev mode, but failed when actually deploying. I found a workaround using the sandbox globals in the fastboot server which enables to push a variable to the app at runtime.

Now I am back at storefront fails to resolve its shoebox as the sandbox only works in fastboot and not on the client. I’ll try to have a look at storefront to get that sorted.

I opened a PR to fix this issue https://github.com/embermap/ember-data-storefront/pull/150

1 Like

Awesome, I just released this as 0.17.1. Thank you so much for fixing it!

1 Like