Getting a Deployable Artifact
Picking up from where we left on in the previous guide, we are going to start to look into how we can work with our project and its files.
You should now be able to go ahead and trigger a Gradle build at the root of the project.
This will trigger the following series of events:
- UI module will produce a jar file at ui/dist/ng-spring-angular-mono-0.0.1-SNAPSHOT.jar
- Gradle Calls node build script
- Gradle bundles contents of build script output (ui/build) into a jar under static/…
- Spring module is built
- Usual Spring Boot Build Process Takes Place
- UI Module jar file is pulled in as a dependency
What we have as a net result is a spring boot project with all of our Angular Static files, JS, HTML, CSS on the classpath.
So we can go ahead and run our application like any other Spring web application:
java -jar spring/build/libs/spring-0.0.1-SNAPSHOT.jar
You may notice a lack of any controller, but that’s ok in our case because by default the
index.html is returned if its on the classpath.
A Quick Note About Development Servers
Before proceeding any further its worth identifying exactly what we have when running in our different modules.
- When running the Spring Boot App from the jar, or indeed simply running the spring boot app at all, we are simply taking the latest snapshot of the UI Build, and adding it to the classpath, then starting the Spring app.
— The Spring Boot application server will be running on port 8080
— If the static files are changed in the UI module this will not be seen until the jar is re-created on the Gradle build.
- When running the Angular app, we are starting an Angular development server, it WILL run in parallel to the tomcat server from the spring boot app, and they will have NO relation to one another.
— The Angular Development server will be serving the Angular application on port 4200
— If the static files are changed this will be seen instantly due to the hot reloading of the angular server.
Because our Tomcat Application Server is going to serve as the API to our frontend, it is important that we stand this up first.
Launching our Spring Module
Go ahead an run the spring boot application from the IDE, if you have any trouble running the spring module then you can run it using Gradle
Launching our Angular Module
If you have not already done so ensure node and npm are installed and install the Angular CLI
npm install -g @angular/cli
Navigate to the UI folder in the project and run the npm start script which in this case will cause ng serve to be executed.
If you now navigate to localhost:4200 you should find that the application has started and is running under the development server.
Make a simple change to the
ui/src/app/app.component.html and confirm the UI updates immediately.
Connecting the Blocks
Since we now have one application server serving up our backend on port 8080, and we have another serving up our frontend on 4200 we need to connect the blocks.
We do this through the use of a proxy.
As it stands there is no connection between the Angular server and the Spring Boot server, if we were to make an Ajax request to our backend we would have to hard code its URL.
However if we introduce a proxy that will only run during development mode, when we have these separate services running they can communicate, but when deployed as a single jar there will be no need for the proxy as requests can be made relative.
- Create a new file in the root of the UI project with the proxy config, name it proxy.conf.json
package.json to ensure the proxy is set up when the development server is started
"start": "ng serve --proxy-config proxy.conf.json",
"build": "ng build",
With this configuration in place, all requests that are submitted from the UI to /api/** will be re-directed to our tomcat application server running on port 8080.
When the app is deployed the same behavior will happen because the static files will be served from the application server they are sending requests to.
In this short but crucial step, we completed the wiring of our application. We have seen how it will be deployed when complete and how we can create a development environment enabling hot reloading of UI changes.
We have run the tomcat server and angular server separately and connected the requests via a proxy so that any ajax request to /api/** can be redirected to our Tomcat application server.