I have the SpringBoot application as BE and Angular as FE. SpringBoot is on port 8553 and Angular is on 4203. So for communicating, I'm using proxy.conf.json where I'm redirecting all the requests from 4203 to 8553 like this:
"/application": {
"target": "http://localhost:8553",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
I'm starting the angular app with a proxy like this:
ng serve app --port 4203 --proxy-config proxy.conf.json --disable-host-check true
Everything is working fine. Now I want to run another SpringBoot instance on a different port 8554 and I want to use the same angular instance and switch between SpringBoot instances. I want to have a dropdown and user to pick one of two different SpringBoot instances, and angular to connect to that instance and proxy all the requests to that instance.
I have tried with two different proxy configs, but I don't know what to switch in runtime between them. Im not sure if this is even possible with my current setup.
I will also try using different environment files and switch them in runtime, if possible. This is more like an infrastructure and architecture problem, and I'm not very good at it :D
Assuming you mean Angular instead of AngularJS, follow these steps:
1. Update proxy.conf.json
Add new proxy configs:
"/api1": {
"target": "http://localhost:8553",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
},
"/api2": {
"target": "http://localhost:8554",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
2. Create ApiUrlService
Make an injectable service ApiUrlService
with a property apiUrl = 'api1'
.
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ApiUrlService {
apiUrl = 'api1'; // Default value
}
3. HTTP Interceptor
Create an HTTP interceptor to replace '/api' with apiUrlService.apiUrl
. Inject ApiUrlService
in the interceptor.
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { ApiUrlService } from './api-url.service';
@Injectable()
export class ApiInterceptor implements HttpInterceptor {
constructor(private apiUrlService: ApiUrlService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const apiReq = req.clone({ url: req.url.replace('/api', `/${this.apiUrlService.apiUrl}`) });
return next.handle(apiReq);
}
}
Don't forget to register the interceptor in your AppModule
:
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { ApiInterceptor } from './api.interceptor';
@NgModule({
imports: [
HttpClientModule,
// other imports
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: ApiInterceptor,
multi: true
}
],
// other module properties
})
export class AppModule { }
4. Switch API URL at Runtime
To change the API URL in runtime, modify apiUrl
value in ApiUrlService
from a form.
Inject ApiUrlService
in your component:
constructor(public apiUrlService: ApiUrlService) {}
Use a select dropdown in your template to switch between '/api1' and '/api2' (remember to import the Angular FormsModule
:
<select [(ngModel)]="apiUrlService.apiUrl">
<option value="api1">API 1 (Port 8553)</option>
<option value="api2">API 2 (Port 8554)</option>
</select>