0

I have an Angular 2 app that will be installed on multiple servers, and needs to access a backend that is also on multiple servers. I'm using the code from this answer, specifically the edit that works with methods other than GET, and it works well if I hardcode the backend URL.

For a given frontend server, the backend it needs to access will always be the same. For example, if the frontend is on "example.com", the backend will always be on "example.com:9080".

I can bundle the app for each different server, changing "localhost:9080" in that answer to "example1.com:9080", "example2.com:9080", etc. as appropriate. This would mean having to make code changes and bundle the app for each server.

Is there a way that I can somehow fetch the URL that I need to access for the backend so I can bundle it once and deploy it to all the servers?

I'm using Angular 2.4.5 and serving the frontend using Apache.

Community
  • 1
  • 1
slickam
  • 13
  • 4
  • can you clarify this a bit more? when you say the app will be installed on multiple servers, and the backend is also multiple servers, do you mean that the app frontend and backend will always be the same URL for each deployment? or are the frontend URL and backend URL going to differ? – Claies Jan 27 '17 at 17:59
  • I think this is what you want: http://stackoverflow.com/questions/37172928/angular-cli-server-how-to-proxy-api-requests-to-another-server – Robin Dijkhof Jan 27 '17 at 18:04
  • @Claies: I added some more information about how it will be deployed. – slickam Jan 27 '17 at 18:15
  • @RobinDijkhof: Sorry, I should have said that I was using Apache to serve the frontend, not ng serve. – slickam Jan 27 '17 at 18:16
  • I believe the proxy config will workwhen you build the application. `ng serve` is just for local development – Robin Dijkhof Jan 27 '17 at 19:41

2 Answers2

0

I'm targeting IIS so i'm using an http handler to resolve this dynamically based on the environment, but you can implement it using a single js file, something like this:

  1. Create a js file containing the settings you want to load into the application in the following way:

    var js = {}; js.settings = { API_URL : 'your_api_url_here' };
  2. Create a class to map those values in your app:

    export class Settings { API_URL: string; }
  3. Be sure that the js file will be loaded before your application scripts, so put it in your index.html:

    &ltscript src="env.js"&gt&lt/script&gt
  4. Now in your app.module, map those values into your Settings class and define how they will be provided:

    
    // needed to avoid the TS compilation error. 
    // This can be placed at the top of your app.module file. 
    declare var js: any;
    
    @NgModule({ 
           imports: [...], 
           declarations: [...], 
           providers: [{
           provide: Settings, useFactory: ()=> { return js.settings; }}] }) 
    export class AppModule{}
    
  5. Now inject the Settings object everywhere you may need it, like this:

    
    export class ServiceBase {
        protected apiUrl: string;
        constructor(private settings: Settings){
            this.apiUrl = settings.API_URL;
    }
    

Hope this works for you as well.

elvin
  • 961
  • 1
  • 9
  • 26
0

Your really do not want to have this in your application. This should be configuration as it depends on the server you're on (in other words, you don't want to have to change your code and rebuild when you add a server at a later point). Therefore, my guess is that you really want to solve this on your apache server. You can consider using ProxyPass and ProxyPassReverse (in httpd.conf or htaccess). That way you don't have to bother worrying about it in your application as there, you would only use relative paths to your api endpoints.

For example, suppose you have your angular app served from example.com, and your backend api lives at example.com:9080/api/.

Your code would simply use /api as the path to your endpoints and the ProxyPass would rewrite those to the backend using:

ProxyPass /api example.com:9080
ProxyPassReverse /api example.com:9080

You would need MOD_PROXY installed (pretty common on most hosts): https://httpd.apache.org/docs/current/mod/mod_proxy.html

MikeOne
  • 4,789
  • 2
  • 26
  • 23