ember-fastboot / ember-cli-fastboot

Server-side rendering for Ember.js apps
http://ember-fastboot.com/
MIT License
851 stars 160 forks source link

No support for FastBoot context only configuration #254

Open martletandco opened 8 years ago

martletandco commented 8 years ago

There is no support for having different config/environment outputs for FastBoot vs browser in the build process (i.e. fastboot.appConfig in dist/package.json vs dist/index.html) even though Ember FastBoot App Server uses fastboot.appConfig from package.json exclusively.

Senario

An application relies on an API. When running in the browser context the application calls the public endpoint as normal. However when running in a FastBoot context the application should call the (sensitive) internal endpoint to avoid a round trip outside.

Unsuitable solutions

Check for isFastBoot on the fastboot service While technically this would work, the internal endpoint would be leaked in the config meta tag in index.html

Use a conditional include/macro/post-process Again, this would technically work, however this would very much be a work around and this problem is something that many people will have.

process.env.EMBER_CLI_FASTBOOT This flag is not useful because "the EMBER_CLI_FASTBOOT environment variable is not set when the FastBoot build actually happens" – ember-cli-fastboot/lib/broccoli/fastboot-build.js#L126.

Possible solutions

Explicitly pass in a flag to config/environment This would require changes to Ember CLI and seems like a slippery slope

config/context The output of config/environment and the context (browser | fastboot) could be passed to a context function to alter the config for the context.

?? Other options?


Not sure what the right move is here but willing to put some effort in to make it happen.

arjansingh commented 8 years ago

@pwfisher and I ran into similar issues, we solved it in our app by creating a configuration service and using that instead of the raw configuration. (e.g., let hostname = this.get('configService.endpoints.backends.foo') instead of let hostname = config.endpoints.backends.foo)

The configuration service is the only one with access to the raw configuration object. It is made aware of the context it's running in, and thus can properly switch out host names (or any other environment specific configuration) for the proper API endpoint.

So as long you're ok with exposing the internal hosts names or addresses in your raw config you should be fine. It's on our list to open-source our config service, but we can't right now because there's too much private logic that we'd have to abstract first.

martletandco commented 8 years ago

Thanks @arjansingh , unfortunately exposing internal host names is not an option for me. I'm looking for a solution that keeps sensitive information in the server (package.json) only.

martletandco commented 8 years ago

@tomdale @rwjblue any chance you could put this on the agenda for the next meeting? I'm getting close to needing a solution and I'd really like to get some direction so my effort isn't misplaced.

tomdale commented 8 years ago

@martletandco Thank you for raising this issue! This is very helpful context and I agree it is something that a lot of people need.

We have been discussing for a while the idea of "targets" in Ember CLI, which, if designed properly, should help address this case. We should make sure we include configuration settings in targets. I opened an issue to track this here: https://github.com/ember-fastboot/ember-cli-fastboot/issues/268

I am hoping to discuss this at the core team face-to-face meeting this weekend and come up with a detailed plan.

martletandco commented 7 years ago

Thanks @tomdale . If I end up needing an interim solution I will link to it here.

martletandco commented 7 years ago

Just doing a dirty sed on deploy for the time being. Will need to change to an Object.assign if I need to deal with too many properties.

sed -i'' -e "s,APIBaseUrl\": \"\",APIBaseUrl\": \"$1\",g" dist/package.json

Redsandro commented 5 years ago

I know this is an old issue, but I'm having the exact same necessity. Is there a recommended way to see whether or not environment.js is being run as FastBoot server side or not?

(If so, please document and close the issue.)

Redsandro commented 5 years ago

What is the recommended way in 2019? This issue plays a bigger role in Kubernetes/Docker deploys where the API and FastBoot server are run on the same machine. The internal API endpoint does not have the same name as the external DNS/HTTPS endpoint for clients.