0

I am currently using proxy.conf.json to configure API url for development. I believe it only works on the local server. How can I configure the API url when deploying it on UAT and Production server? I would like to change the API url on the server without re-building the entire application.

proxy.conf.json:

{
    "/api": {
      "target": "http://api_server:88",
      "secure": false,
      "pathRewrite": {
      "^/api": ""
    },
      "changeOrigin": true
    }
  }

api.service.ts:

get<T>(params: any = {}) : Observable<T> {
    return this.http.get<T>("/api/data", {params: params});
}
developer
  • 1,401
  • 4
  • 28
  • 73

2 Answers2

1

The proxy configurations in the proxy.conf.json file is for your Webpack dev server to run your Angular application locally using ng serve command. It should not be used for Production and staging environments. You can find details about this in the official Angular docs page.

If you want to add a similar feature to your NodeJs or any other server which is hosting your angular application, check if API gateway plugins are available for the server you are using.

Check this article if you are not aware of API gateways.

Shravan
  • 1,182
  • 8
  • 21
  • Thanks Shravan. I am deploying it on IIS. I was wondering if there is any easier option than adding additional Nginx dependency. I am expecting it should be something built-in as it is a very basic ask. – developer Jul 09 '21 at 12:40
0

This way has been working great for us:

  1. Create a custom HTTP Service and build a function that will check the current URL.

custom-http.service.ts <- You can name this specific to your company / app name

@Injectable()
export class CustomHttpService {

    constructor(private http: HttpClient) {
    }

    public getCurrentEnvironment(): string {
        const host = window.location.origin;
        let env = "";
        switch(host) {
            case 'http://localhost:4200': {
                env = 'LOCALDEV';
                break;
            }
            case 'https://my-test-site.azurewebsites.net': {
                env = 'TEST';
                break;
            }
            case 'https://my-prod-site.azurewebsites.net': {
                env = 'PROD';
                break;
            }
            case 'https://customdomain.com': {
                env = 'PROD';
                break;
            }
            default: {
                env = 'PROD';
                break;
            }

        }
        return env;
    }

    public get(url: string): Observable<any> {
        return this.http.get(url);
    }

    public getWithHeader(url: string, header: HttpHeaders): Observable<any> {
        return this.http.get(url, {headers: header});
    }

    public post(url: string, body: any): Observable<any> {
        return this.http.post(url, body);
    }

    public put(url: string, body: any): Observable<any> {
        return this.http.put(url, body);
    }

    public delete(url: string): Observable<any> {
        return this.http.delete(url);
    }
}

You can call getCurrentEnvironment() from any where in your app to know which environment you are on.

  1. Create a URL helper service, this will pass in the correct API url for your specific environment.
@Injectable()
export class URLHelper {
    constructor(private httpService: CustomHttpService) {

    }

    private env: string = this.httpService.getCurrentEnvironment();
    private Server: string = this.getServerUrl(this.env);

    getServerUrl(env: string): string {
        let server = "";
        switch (env) {
            case "LOCALDEV": {
                server = "http://localhost/project/";
                break;
            }
            case "TEST": {
                server = "https://my-test-site-api.azurewebsites.net/";
                break;
            }
            case "PROD": {
                server = "https://my-prod-site-api.azurewebsites.net/";
                break;
            }
            default: {
                console.error('No Env Found');
                server = "https://my-prod-site-api.azurewebsites.net/";
            }
        }
        return server;
    }

    // Here you will define all the API endpoints your app will use and 'this.Server ' will contain the proper host API server url at runtime for each environment.
    public User = this.Server + 'api/User';
  1. Usage. To use this now, all you need to do is in any of your feature module services, add CustomHttpService and URLHelper into the constructor
@Injectable()
export class AdminService {

    constructor(private urlHelper: URLHelper, private httpService: CustomHttpService) { }

    getUser(): Observable<any> {
        return this.httpService.get(this.urlHelper.User);
    }

}
Brian Smith
  • 1,467
  • 15
  • 31
  • Thanks Brian. It looks like a good option. How do you specify which environment to use on a server? Is it during the build time? e.g. ng serve -env=TEST? – developer Jul 09 '21 at 12:38
  • The getCurrentEnvrionment looks at the current URL in the browswer `window.location.origin`. All you need to do is `ng serve` and open your broswer to http://localhost:4200 and the getCurrentEnvrionment will return LOCALDEV and your API host will use `http://localhost/project/` in this case. You don't have to do anything extra. – Brian Smith Jul 09 '21 at 12:41
  • i see, makes sense. The only downside is any url change will require rebuilding the angular application while it should really be a config change. Do you agree? – developer Jul 09 '21 at 12:44
  • URLs should not be changing often and yes, if you add a new environment or change the UI host / API host, it will require a code push but that is also very minimal. – Brian Smith Jul 09 '21 at 12:51
  • Yes, I agree. I am thinking to use a json file in assets folder and get the url from the JSON file so it can be changed without compiling. Do you see any downside using the approach? – developer Jul 09 '21 at 12:54
  • Nope, that will work just fine too. Makes it easier to update without code push. – Brian Smith Jul 09 '21 at 12:58