• Stars
    star
    342
  • Rank 123,697 (Top 3 %)
  • Language
    TypeScript
  • Created about 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Quick tutorial on how to create a Spring Boot app with Angular front end using Maven and modern front end tooling

Creating a New Application with Spring Boot and Angular

Spring Boot works great as a back end for an Angular application but it can be difficult to get the ball rolling. Most Spring users are comfortable with Java and the tools that are used to create and build the backend server. The front end can be written with plain old JavaScript as long as it is relatively simple, and you are willing to search for the rare examples and tutorials in this style. But these days you are much more likely to find documentation and tutorials that use tools like Typescript, node.js, npm and the Angular CLI.

This article shows you how to do that and keep your Spring Boot application intact. Much of the advice would apply equally well to other front end frameworks (anything that can be built using npm or similar). We use Maven, but similar tools are available for Gradle users. The goal is to have a single application that has Spring Boot and Angular, that can be built and developed by anyone who has knowledge of either ecosystem, and does not feel awkward or unidiomatic to either.

Create a Spring Boot Application

Whatever you normally do to create a new Spring Boot application, do that. For example you could use your IDE features. Or you could do it on the command line:

$ curl start.spring.io/starter.tgz -d dependencies=web | tar -zxvf -
$ ./mvnw install

Now we’ll take that application and add some Angular scaffolding. Before we can do anything with Angular, we have to install npm.

Install Npm Locally

Installing npm is fraught with issues, including but not limited to how to get it working as part of your build automation. We are going to use the excellent Maven Frontend Plugin from Eirik Sletteberg. The first step is to add it to our pom.xml:

pom.xml
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>1.12.0</version>
            <configuration>
                <nodeVersion>v16.13.1</nodeVersion>
            </configuration>
            <executions>
                <execution>
                    <id>install-npm</id>
                    <goals>
                        <goal>install-node-and-npm</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

and then

$ ./mvnw generate-resources
$ ls node*

Loads of stuff has been installed in the top level directory. Once the downloaded files are cached in your local Maven repository, it won’t take long to run this for every build.

Install Angular CLI

To build an Angular app these days it really helps to use the CLI provided by the Angular team. We can install it using the npm that we just got using the plugin. First create a convenient script to run npm from the local installation (in case you have others on your path):

$ cat > npm
#!/bin/sh
cd $(dirname $0)
PATH="$PWD/node/":$PATH
node "node/node_modules/npm/bin/npm-cli.js" "$@"
$ chmod +x npm

and then run it to install the CLI:

$ ./npm install @angular/cli
Note
Windows users can find a similar looking npm.cmd script in node/node_modules/npm/bin. If you copy it to the root of the project, and edit to match the local paths, you can use it in the same way.

Then create a similar wrapper for the CLI itself, and test it quickly:

$ cat > ng
#!/bin/sh
cd $(dirname $0)
PATH="$PWD/node/":"$PWD":$PATH
node_modules/@angular/cli/bin/ng.js "$@"
$ chmod +x ng
$ ./ng --version
    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / β–³ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
           |___/
Angular CLI: 13.0.4
Node: 16.13.1
OS: linux x64
...
Note
Windows user can try the same trick with ng.cmd as with npm.cmd to get a local command to run the Angular CLI.

Create an Angular App

The Angular CLI can be used to generate new application scaffolding, as well as other things. It’s a useful starting point, but you could at this point grab any existing Angular app and put it in the same place. We want to work with the Angular app in the top level directory to keep all the tools and IDEs happy, but we also want make it look like a regular Maven build.

Create the app with the CLI:

$ ./ng new client # add --minimal here if you want to skip tests

and then move it into the root of the project:

$ cat client/.gitignore >> .gitignore
$ rm -rf client/node* client/src/favicon.ico client/.gitignore client/.git
$ cp -rf client/* .
$ cp client/.??* .
$ rm -rf client
$ sed -i -e 's,dist/client,target/classes/static,' angular.json

We discarded the node modules that the CLI installed because we want the frontend plugin to do that work for us in an automated build. We also edited the angular.json (a bit like a pom.xml for the Angular CLI app) to point the output from the Angular build to a location that will be packaged in our JAR file.

Building

Add an execution to install the modules used in the application:

<execution>
    <id>npm-install</id>
    <goals>
        <goal>npm</goal>
    </goals>
</execution>

Install the modules again using ./mvnw generate-resources and check the result (the versions will differ for you).

$ ./ng version
    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / β–³ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
           |___/
Angular CLI: 13.0.4
Node: 16.13.1
OS: linux x64
Angular: 13.0.3
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect       0.1300.4
@angular-devkit/build-angular   13.0.4
@angular-devkit/core            13.0.4
@angular-devkit/schematics      13.0.4
@angular/cli                    13.0.4
@schematics/angular             13.0.4
rxjs                            7.4.0
typescript                      4.4.4

At this point, the tests work:

$ ./ng test
Generating browser application bundles (phase: setup)...09 12 2021 13:57:18.567:WARN [karma]: No captured browser, open http://localhost:9876/
09 12 2021 13:57:18.576:INFO [karma-server]: Karma v6.3.9 server started at http://localhost:9876/
09 12 2021 13:57:18.576:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
09 12 2021 13:57:18.590:INFO [launcher]: Starting browser Chrome
βœ” Browser application bundle generation complete.
09 12 2021 13:57:21.749:WARN [karma]: No captured browser, open http://localhost:9876/
09 12 2021 13:57:21.797:INFO [Chrome 94.0.4606.71 (Linux x86_64)]: Connected on socket Fh4AKRcSDz0TEUkyAAAB with id 93745390
βœ” Browser application bundle generation complete.
Chrome 94.0.4606.71 (Linux x86_64): Executed 3 of 3 SUCCESS (0.133 secs / 0.119 secs)
TOTAL: 3 SUCCESS

and if you add this as well:

    <execution>
        <id>npm-build</id>
        <goals>
            <goal>npm</goal>
        </goals>
        <configuration>
            <arguments>run-script build</arguments>
        </configuration>
    </execution>

then the client app will be compiled during the Maven build.

Stabilize the Build

If you want a stable build you should put a ^ before the version of @angular/cli in your package.json. It isn’t added by default when you do ng new, but it protects you from changes in the CLI. Example:

package.json
...
"devDependencies": {
    "@angular/cli": "^13.0.4",
...

Development Time

You can build continuously with

$ ./ng build --watch

Updates are built (quickly) and pushed to target/classes where they can be picked up by Spring Boot. Your IDE might need to be tweaked to pick up the changes automatically (Spring Tool Suite does it out of the box).

That’s it really, but we can quickly look into a couple of extra things that will get you off the ground quickly with Spring Boot and Angular.

VSCode

Microsoft VSCode is quite a good tool for developing JavaScript applications, and it also has good support for Java and Spring Boot. If you install the "Java Extension Pack" (from Microsoft), the "Angular Essentials" (from Jon Papa) and the "Latest TypeScript and JavaScript Grammar" (from Microsoft) you will be able to do code completion and source navigation in the Angular app (all those extensions and discoverable from the IDE). There are also some Spring Boot features that you need to download and install (in Extensions view click on top right and choose Install from VSIX…​) at http://dist.springsource.com/snapshot/STS4/nightly-distributions.html.

What VSCode doesn’t have currently is automatic detection of npm build tools in the project itself (and ours is in . so we need it). So to build from the IDE you might need to add a .vscode/tasks.json something like this:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "ng-build",
            "type": "shell",
            "command": "./ng build"
        },
        {
            "label": "ng-watch",
            "type": "shell",
            "command": "./ng build --watch"
        }
    ]
}

With that in place your Tasksβ†’Run Task…​ menu should include the ng-watch option, and it will run the angular build for you and re-compile if you make changes. You could add other entries for running tests.

Adding Bootstrap

You can add basic Twitter Bootstrap features to make the app look a bit less dull (taken from this blog):

$ ./npm install bootstrap --save

and update styles.css to add the new content:

styles.css
@import "~bootstrap/dist/css/bootstrap.css";

Basic Angular Features

Some basic features are included in the default scaffolding app, including the HTTP client, HTML forms support and navigation using the Router. All of them are extremely well documented at angular.io, and there are thousands of examples out in the internet of how to use those features.

As an example, lets look at how to add an HTTP Client call, and hook it up to a Spring @RestController. In the front end app-root component we can add some placeholders for dynamic content:

app.component.html:
<div style="text-align:center"class="container">
  <h1>
    Welcome {{title}}!
  </h1>
  <div class="container">
    <p>Id: <span>{{data.id}}</span></p>
    <p>Message: <span>{{data.content}}</span></p>
  </div>
</div>

so we are looking for a data object in the scope of the component:

app.component.ts:
import { Component } from '@angular/core';
import {HttpClient} from '@angular/common/http';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Demo';
  data = {}  as any;
  constructor(private http: HttpClient) {
    http.get('resource').subscribe(data => this.data = data);
  }
}

Notice how the AppComponent has an HttpClient injected into its constructor. In the module definition we need to import the HttpClientModule as well, to enable the dependency injection:

app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

In our Spring Boot application we need to service the /resource request and return an object with the right keys for the client:

DemoApplication.java:
@SpringBootApplication
@Controller
public class DemoApplication {

  @GetMapping("/resource")
  @ResponseBody
  public Map<String, Object> home() {
    Map<String, Object> model = new HashMap<String, Object>();
    model.put("id", UUID.randomUUID().toString());
    model.put("content", "Hello World");
    return model;
  }

...

}

If you look at the source code in Github you will also notice that there is a test for the backend interaction in app.component.spec.ts (thanks to this Ninja Squad blog). The pom.xml has been modified to run the Angular e2e tests at the same time as the Java tests.

Conclusion

We have created a Spring Boot application, added a simple HTTP endpoint to it, and then added a front end to it using Angular. The Angular app is self-contained, so anyone who knows the tools can work with it from its own directory. The Spring Boot application folds the Angular assets into its build and a developer can easily update and test the front end from a regular IDE by running the app in the usual way.

More Repositories

1

spring-boot-startup-bench

Benchmarks for Spring Boot startup
Java
294
star
2

spring-boot-aspectj

Sample applications showing how to use AspectJ with Spring Boot
Java
164
star
3

spring-boot-memory-blog

Spring Boot Memory Performance Blog
152
star
4

sparklr-boot

Demo OAuth2 provider with Spring Boot
Java
137
star
5

spring-boot-micro-apps

Java
131
star
6

kubernetes-intro

Shell
119
star
7

spring-boot-legacy

Support for legacy (Servlet 2.5) apps in Spring Boot
Java
100
star
8

spring-boot-allocations

Java
99
star
9

reactive-notes

Java
89
star
10

spring-security-architecture

High level documentation for Spring Security and users of Spring Boot
79
star
11

inner-loop-boot-k8s

Java
65
star
12

spring-boot-ratpack

Spring Boot wrapper for Ratpack
Java
53
star
13

spring-boot-jersey

Jersey autoconfig support for Spring Boot
Java
51
star
14

spring-boot-java-10

Java
36
star
15

spring-security-rsa

Java
30
star
16

spring-boot-operator

Go
29
star
17

main-branch-switch

Scripts for switching a Github repository to use a "main" branch
Shell
25
star
18

mustache-sample

Java
24
star
19

spring-boot-js-demo

These samples explore the different options that Spring Boot developers have for using Javascript and CSS on the client (browser) side of their application.
Java
23
star
20

rsocket-test-server

Java
23
star
21

spring-boot-sample-data-eclipselink

Java
23
star
22

dist-tx

Source code for distributed transactions article from 2008, updated to use Spring Boot
Java
19
star
23

dependency-hell

Short article on a dependency management issue with Maven 3.3
Shell
16
star
24

docker-services

Dockerfile
15
star
25

spring-oauth2-integration-tests

Integration tests and demo apps for OAuth2 with Spring
Java
14
star
26

spring-boot-mustache

Spring Boot autoconfiguration for JMutsache (web and nonweb template rendering)
Java
14
star
27

spring-boot-auto-reflect

Java
13
star
28

spring-boot-spa

Shell
12
star
29

spring-batch-gemfire

Gemfire integration for Spring Batch
Java
12
star
30

protobuf-wasm

Shell
12
star
31

presos

Presentations for conferences and user groups etc.
HTML
11
star
32

frontend-microservices

Java
11
star
33

auth-server-client

Shell
11
star
34

log4j-utils

Log4j Utilities
Java
10
star
35

spring-todo-mvc

Java
10
star
36

skaffold-devtools-demo

Java
9
star
37

spring-batch-gridgain

GridGain integration for Spring Batch
Java
8
star
38

spring-wasm-demo

C
8
star
39

native-grpc

Java
7
star
40

spring-boot-initializer

Java
6
star
41

payments-demo

Java
6
star
42

spring-security-oauth2-hydra

Java
6
star
43

spring-boot-aot

Java
6
star
44

cloud-middleware-blog

Blog text and sample project for article on spring.io in 2015
Java
6
star
45

qcon-workshop-2016

Shell
6
star
46

spring-boot-lazy-actuator

Java
5
star
47

hello-wasm

C
5
star
48

http-amqp-tunnel

Tunnel HTTP over AMQP using Spring Integration
Java
5
star
49

spring-boot-features

Java
5
star
50

spring-spreadsheet

Spring spreadsheet support (Excel, OpenOffice etc.)
Java
5
star
51

gs-spring-boot-docker

Spring Boot with Docker :: Learn how to create a Docker container from a Spring Boot application with Maven or Gradle
Java
5
star
52

two-factor

Shell
4
star
53

spring-boot-factory-aspects

Java
4
star
54

java-function-benchmarks

Java
4
star
55

riff-http

Shell
4
star
56

spring-data-simple

Simple Repository metadata for repositories created "manually" (i.e. not auto-generated)
Java
4
star
57

stream-startup

Java
4
star
58

jlink-petclinic

Dockerfile
4
star
59

spring-batch-grid

Grid adapters for Spring Batch
Java
4
star
60

lambda-aws-demo

Demo for AWS custom runtime native image
Java
4
star
61

nix-config

Emacs Lisp
4
star
62

async-wasm

C
4
star
63

refresh

Java
4
star
64

cflogin

Authorization Server for "fully-leaded" Cloud Foundry access tokens
Java
3
star
65

spring-config-operator

Go
3
star
66

openapi-rust

Rust
3
star
67

spring-boot-legacy-agent

Provides a Java agent that allows an app that was compiled with Spring Boot 2.0 to run with earlier versions.
Java
3
star
68

spring-restdocs-messaging

Java
2
star
69

spring-boot-proto

Java
2
star
70

petflix

Java
2
star
71

pod-mutating-webhook

Go
2
star
72

simple-gateway

simple-gateway
2
star
73

spring-petclinic-jpa

Java
2
star
74

gateway-wasm

Java
2
star
75

spring-boot-archetypes

Automation scripts for publishing Spring Boot Samples as Maven archetypes
Shell
2
star
76

SpringCloudWorkshop

TSQL
2
star
77

spring-controller

Java
2
star
78

cf-memory-tests

Java
2
star
79

openapi-demo

Java
2
star
80

sagan-wiki

2
star
81

nix-demo

Dockerfile
2
star
82

spring-xd-module-runner

2
star
83

native-config-server

Dockerfile
2
star
84

spring-cloud-stream-binder-servlet

Java
2
star
85

js-utils

JavaScript
1
star
86

ubuntu-make-vm-images

Shell
1
star
87

teavm-demo

Java
1
star
88

nix-cloud

Shell
1
star
89

spring-oauth2-integration-tests-xml

Integration tests and demo apps for OAuth2 with Spring using XML for the OAuth bits
Java
1
star
90

vanilla-orm

Java
1
star
91

spring-boot-bindings

Go
1
star
92

dotnet-test

Get dotnet working on Linux
Dockerfile
1
star
93

github-admin

Java
1
star
94

doppler-metrics-sample

Java
1
star
95

azure-custom-handler

HCL
1
star
96

spring-cloud-deployer-thin

Java
1
star
97

spring-service-operator

Go
1
star
98

hello-nix-java

Java
1
star
99

hello-rust

Java
1
star
100

dispatcher-servlet-container

Java
1
star