3

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?

Jorge Riv
  • 141
  • 4

2 Answers2

6

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
Ewan
  • 70,664
  • 5
  • 76
  • 161
2

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

TurtleKwitty
  • 301
  • 1
  • 8
  • 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 09 '18 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 09 '18 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 09 '18 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 09 '18 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 09 '18 at 15:48
  • Yes, project is re-compiled after change in environment file. look at https://medium.com/beautiful-angular/angular-2-and-environment-variables-59c57ba643be – Jorge Riv Aug 09 '18 at 17:13
  • @JorgeRiv: If you need to re-build for every environment, then by definition what you put into production is something else than what you tested. Is your QA department aware of that and do they agree with that? – Bart van Ingen Schenau Aug 10 '18 at 12:39
  • @Bart van Ingen Schenau: I failed to express that exact properly so thank you for bringing it back. – TurtleKwitty Aug 10 '18 at 12:41
  • Guys, are you Angular developers? different builds for different targets is pretty standard, environment files are even created by the angular CLI when scaffolding projects. Angular is usually written in TS which browsers do not understand, it needs to be translated into JS, there is no way that you can change configuration (.ts files) and not need to compile the source. Google usually hires pretty smart guys, if you think they are wrong and have a better way please share in Q/A form and share link. Find doc here (look at environments folder): https://angular.io/guide/quickstart#the-src-folder – Jorge Riv Aug 10 '18 at 13:54