We are developing an angular 5 application that must run in different environments (dev, qa, int, uat, prod), and connect to different APIs depending on the environment. We have traditionally have only 4 environments and we have a environment file for each with environment variables.

But now with the introduction of the 5th environment - integration (int) - Instead of adding a different release channel in Octopus Deploy with a different build (that use environment variables), they want the app to handle the configuration by detecting the domain in the url (at run time) and select configuration in a switch/case structure. e.g:

let apiUrl = 'https://api.example.com/v2';
const location = window.location.origin;
switch(location){
  case 'https:dev.hostname.domain':
  apiUrl = 'https://dev-api.example.com/v2';
  break;
  case 'https:qa.hostname.domain':
  apiUrl = 'https://qa-api.example.com/v2';
  break;
  case 'https:int.hostname.domain':
  apiUrl = 'https://int-api.example.com/v2';
  break;
  case 'https:uat.hostname.domain':
  apiUrl = 'https://uat-api.example.com/v2';
  break;
}

This is because some people are resisting to modify the CI tool configuration to add the new release channel. But this doesn't feel right to me, I think the environment variables is a better solution (different environment file is used depending on the target in the compilation phase). e.g:

//QA environment file example
export const environment: Environment = {
  production: 'false',
  apiUrl = 'https://qa-api.example.com/v2',
  otherEnvVar: 'whatever',
}

And then importing the environment where needed:

//Some app file
import {environment} from '../environments/environment';
// ... my code ...

But when trying to explain the reason I can not think of anything other than this solution seems 'ugly' to me (which is not a valid reason). So now I'm wondering if is there a valid reason to have environment variables separated from the application logic.

What would be the superior solution and why? or both are equally valid?

up vote 6 down vote accepted

You should definitely modify the CI to correctly set the configuration for the environment rather than trying to work it out from the Url at runtime.

You should use Ocotpus Deploy to replace config variables with its scoped project variables when you deploy.

The real reason for this is that the code shouldn't know about the potential environments it might be deployed to. I should be able to deploy the code without having to use an approved url.

However, if you are looking for a list of arguments against the idea..

  • A mistake in the url switch (such as missing out the //) will make it non functional in that env
  • The non live server urls will be exposed to users of the live url
  • Users can easily change the host header by editing their hosts file
  • What about internationalisation? .com .co.uk .ie etc
  • If the Api domain changes it will require a code change rather than a config setting change
  • What about healthchecks from inside the loadbalancer, wont they come in on https://machinename.example.com

The obvious answer would be easier configuration; if say you need to add yet another environment youd only need to make a new environment file, rather than modify and recompile the code, or say you needed to change the API URL or what have you without change in the code you can do so using the environment file.

Essentially, in this case its better to use the environment file as setup cause you dont need to handle special things outside o changing a couple variables, and this technique allows you to do so easily

  • I agree with the use of environment files but I don't think the need to modify and recompile the code is going to be accepted as a good reason since after creating a new environment file we still need to re-compile the application for that environment. =/ – Jorge Riv Aug 9 at 15:31
  • Ah okay, so then its not only information in the environment file that changes. I had assumed that the code outside the API was environment agnostic, my bad. Maybe then, you should clarify in your question what the différences are in the programs for the various environments, that might help guide to a better answer – TurtleKwitty Aug 9 at 15:34
  • When running ng build --env=prod command, angular cli replace the default environment file with the one specific to that environment while compiling the app. Thus any modification in the environment file requires a new build to be reflected in the running app. – Jorge Riv Aug 9 at 15:43
  • So jsut to be sure, you mention that you need to recompile the code, but then say that the only difference is the change in the environment file? – TurtleKwitty Aug 9 at 15:46
  • The way i see it, if you let your build procedure manage the environment file on code change that doesnt mena you cant modify the environment file for testing or what have you, youre only restricting yourself without sense it seems. That being said, I do understand the want for the defaults to reflect the right values and what not but its not necessary while testing only environment changes, once the testing is odne update the defaults nad leave things as is, no ? – TurtleKwitty Aug 9 at 15:48

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.