Problem that I have recently faced when starting new project with the use of Spring Boot and Angular, is correctly accessing/using my backend API for providing data to the client.
I have develop some very basic CRUD application that simply is responsible for displaying a list of employees.
The API url for getting list of employees is: http://localhost:8080/api/v1/employees and the response looked like that:
Now I wanted to use my API, to deliver data to the client/angular application. I created an employee.service that simply makes a call to the API
import {Injectable} from '@angular/core'; import {HttpClient} from "@angular/common/http"; import {Observable} from "rxjs"; import {Employee} from "../model/employee"; @Injectable({ providedIn: 'root' }) export class EmployeeService { private baseURL = "/api/v1/employees" constructor(private httpClient: HttpClient) { } getEmployeesList(): Observable<Employee[]> { return this.httpClient.get<Employee[]>(`${this.baseURL}`) } }
When I refreshed my application I have noticed in the firebug, that there was a call to the API that did not exist. Call was on port 4200, and not on 8080 – my backend port. Here is this error that I got:
I could of course hardcode the full url in my service using localhost:8080, so it would be:
private baseURL = "http://localhost:8080/api/v1/employees"
but this is for sure not the way to go, especially when you are going to deploy app on production server sooner or later. Nevertheless, just to see what will happen, I changed the url in the service and checked what has happened. I saw well known CORS error
A correct solution for this problem is to use a proxy!
You have to create a new file called proxy.config.json file and add appropriate configuration, so angular would make a call to all API endpoints using exactly this configuration. This file in my case looked like this:
{ "/api/*": { "target": "http://localhost:8080", "secure": false, "logLevel": "debug" } }
File should be placed in the root folder of angular project. As you can see few things are defined in here:
- /api/* – all calls to this urls, should use ‘target’ url
- secure: false – we do not use https
- logLevel: debug – could be very helpful
Last thing that need to be done is the change in the package.json file, in the ng start definition, it should now include the use of proxy file. It should be done like that:
"scripts": { "ng": "ng", "start": "ng serve --proxy-config proxy.config.json", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test" },
Now when I run ng start, all data is finally passed from the backend application to the client
And that is all! I hope it will help someone one day