This blog post is to explain how to build a Spring Boot application with Angular as the frontend UI with Maven as build tool.
Goals:
1) During development run the server separately (spring-boot with live reload)
2) During development run the client separately (Angular with live reload)
3) During dev, Angular UI should be able to call the Sprint Boot RESTFul endpoints even when running separately
4) Build should however be a single Spring Boot jar with UI working as usual (without any change to REST calls).
We first create a multi-module Maven project named 'spring-boot-ang-sample' with pom packaging with includes two child modules, like:
<modules>
<module>spring-boot-ang-sample-ui</module>
<module>spring-boot-ang-sample-service</module>
</modules>
There is nothing much else in the pom. We then create the Spring Boot project 'spring-boot-ang-sample' which is a regular spring boot project with devtools included for live reload. We also create a rest controller class with endpoint api/time/local which just returns a simple JSON with server's time, like:
{"type":"Local","serverTime":"2019-12-24T14:26:21.501"}
We can run this project with mvn spring-boot:run and when we hit localhost:8080/api/time/local we should see the response as above. Now, we are able to do the dev-test cycle for the server.
Next, we create the Angualar project 'spring-boot-ang-sample-ui'. We do this with Angular cli commands, like 'ng new'. This will create the regular angular project and we can run this with ng serve. We can then use the UI at localhost:4200. The changes we make to the UI will reflect with live reload.
The UI code makes calls to the server end points. But, we have a catch here. The server runs in a different port so, but, the calls from within Angular will go only to 4200 or the port which client runs.
Angular provides a nice feature to proxy calls to server: proxying
This is a very useful feature. So, we will make use of this to setup a proxy file wherein, all the calls for 4200/api will goto 8080. This helps us to run client and server separately in dev mode and can develop the interaction freely without worrying about code changes.
When building the project (for deployment), we will make use of the 'frontend-maven-plugin' from 'com.github.eirslett'. This plugin installs node and runs the build for the project. This is useful if you are running the build from say Jenkins where there is no node currently installed.
Remember that the 'spring-boot-ang-sample-ui' project is just an Angular project. So, let's first create the pom.xml so that it becomes a child module of the 'spring-boot-ang-sample' parent project.
Next, we change the angular output path of the angular build to go and reside in the 'spring-boot-ang-sample-service' project under 'src/main/resources/static'. This is a requirement for a spring-boot project to serve web pages. Note that we're not placing it within src/main/resources directly as the Java project resources can be kept separate and clean. The output path is changed, like:
"outputPath": "../spring-boot-ang-sample-service/src/main/resources/static",
Now, when run 'ng build' or when we run mvn clean install on the UI project, the distribution goes and sits in the static folder of the Spring-boot project. Next, when we build the Spring boot project as a jar (mvn clean install), the static resources (web pages ) become part of the jar. After the jar is build navigate to the target folder and run the jar, like:
'java -jar spring-boot-ang-sample-service-1.0.jar'
Now, we can navigate to http://localhost:8080. Note that we can't navigate to 4200 and try to access the web app. In build, the whole web application runs in 8080 and web pages are accessible.
Also, the RESTFul API (endpoints) are accessible as usual at http://localhost:8080/api.
Now, let's hit the endpoint localhost:8080/api/time/local and we should see the same JSON as we saw above. Now, navigate to localhost:8080/, you should see the web page and hitting on the button hits the server and brings back the data and displays it. Note that all along we just use Angular HTTPClient to simply access the 'api/time/local' endpoint.
If you notice above, we built the UI project first and then the server project. This is because, in the build, we need the latest web distribution to be available at src/main/resources/static before the spring boot project is built.
Hence, if you notice the parent project pom, the module order is mentioned as UI coming first and then the services. So, when we run 'mvn clean install' on the parent project 'spring-boot-ang-sample', the UI project gets built first and then the service gets built. The final jar is present in the target folder of the service.
Also note that, the api is also accessible separately should you decide to use it to access from elsewhere like mobile apps. Thus, we have achieved the 4 goals mentioned.
Important: Also, note the files that have been ignored from git commit(s). Apart from the usual 'target' folder and IDE specific files, we have also ignored the 'src/main/resources/static' folder from commit. This is because, this has to be built fresh every time to reflect the latest UI changes, so, no one should commit these files to the repo.
The complete source code is available in my Github repo
References:
https://dzone.com/articles/building-a-web-app-using-spring-boot-angular-6-and
https://dzone.com/articles/simplified-building-web-application-using-spring-b
https://dzone.com/articles/angular-7-spring-boot-application-hello-world-exam
Goals:
1) During development run the server separately (spring-boot with live reload)
2) During development run the client separately (Angular with live reload)
3) During dev, Angular UI should be able to call the Sprint Boot RESTFul endpoints even when running separately
4) Build should however be a single Spring Boot jar with UI working as usual (without any change to REST calls).
We first create a multi-module Maven project named 'spring-boot-ang-sample' with pom packaging with includes two child modules, like:
<modules>
<module>spring-boot-ang-sample-ui</module>
<module>spring-boot-ang-sample-service</module>
</modules>
There is nothing much else in the pom. We then create the Spring Boot project 'spring-boot-ang-sample' which is a regular spring boot project with devtools included for live reload. We also create a rest controller class with endpoint api/time/local which just returns a simple JSON with server's time, like:
{"type":"Local","serverTime":"2019-12-24T14:26:21.501"}
We can run this project with mvn spring-boot:run and when we hit localhost:8080/api/time/local we should see the response as above. Now, we are able to do the dev-test cycle for the server.
Next, we create the Angualar project 'spring-boot-ang-sample-ui'. We do this with Angular cli commands, like 'ng new'. This will create the regular angular project and we can run this with ng serve. We can then use the UI at localhost:4200. The changes we make to the UI will reflect with live reload.
The UI code makes calls to the server end points. But, we have a catch here. The server runs in a different port so, but, the calls from within Angular will go only to 4200 or the port which client runs.
Angular provides a nice feature to proxy calls to server: proxying
This is a very useful feature. So, we will make use of this to setup a proxy file wherein, all the calls for 4200/api will goto 8080. This helps us to run client and server separately in dev mode and can develop the interaction freely without worrying about code changes.
When building the project (for deployment), we will make use of the 'frontend-maven-plugin' from 'com.github.eirslett'. This plugin installs node and runs the build for the project. This is useful if you are running the build from say Jenkins where there is no node currently installed.
Remember that the 'spring-boot-ang-sample-ui' project is just an Angular project. So, let's first create the pom.xml so that it becomes a child module of the 'spring-boot-ang-sample' parent project.
Next, we change the angular output path of the angular build to go and reside in the 'spring-boot-ang-sample-service' project under 'src/main/resources/static'. This is a requirement for a spring-boot project to serve web pages. Note that we're not placing it within src/main/resources directly as the Java project resources can be kept separate and clean. The output path is changed, like:
"outputPath": "../spring-boot-ang-sample-service/src/main/resources/static",
Now, when run 'ng build' or when we run mvn clean install on the UI project, the distribution goes and sits in the static folder of the Spring-boot project. Next, when we build the Spring boot project as a jar (mvn clean install), the static resources (web pages ) become part of the jar. After the jar is build navigate to the target folder and run the jar, like:
'java -jar spring-boot-ang-sample-service-1.0.jar'
Now, we can navigate to http://localhost:8080. Note that we can't navigate to 4200 and try to access the web app. In build, the whole web application runs in 8080 and web pages are accessible.
Also, the RESTFul API (endpoints) are accessible as usual at http://localhost:8080/api.
Now, let's hit the endpoint localhost:8080/api/time/local and we should see the same JSON as we saw above. Now, navigate to localhost:8080/, you should see the web page and hitting on the button hits the server and brings back the data and displays it. Note that all along we just use Angular HTTPClient to simply access the 'api/time/local' endpoint.
If you notice above, we built the UI project first and then the server project. This is because, in the build, we need the latest web distribution to be available at src/main/resources/static before the spring boot project is built.
Hence, if you notice the parent project pom, the module order is mentioned as UI coming first and then the services. So, when we run 'mvn clean install' on the parent project 'spring-boot-ang-sample', the UI project gets built first and then the service gets built. The final jar is present in the target folder of the service.
Also note that, the api is also accessible separately should you decide to use it to access from elsewhere like mobile apps. Thus, we have achieved the 4 goals mentioned.
Important: Also, note the files that have been ignored from git commit(s). Apart from the usual 'target' folder and IDE specific files, we have also ignored the 'src/main/resources/static' folder from commit. This is because, this has to be built fresh every time to reflect the latest UI changes, so, no one should commit these files to the repo.
The complete source code is available in my Github repo
References:
https://dzone.com/articles/building-a-web-app-using-spring-boot-angular-6-and
https://dzone.com/articles/simplified-building-web-application-using-spring-b
https://dzone.com/articles/angular-7-spring-boot-application-hello-world-exam
No comments:
Post a Comment