spring-boot-angular

by dsyer

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

245 Stars 98 Forks Last release: Not found 42 Commits 0 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

= 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 https://github.com/eirslett/frontend-maven-plugin[Maven Frontend Plugin] from Eirik Sletteberg. The first step is to add it to our
pom.xml
:

.pom.xml

    
        
            org.springframework.boot
            spring-boot-maven-plugin
        
        
            com.github.eirslett
            frontend-maven-plugin
            1.6
            
                v9.11.2
            
            
                
                    install-npm
                    
                        install-node-and-npm
                    
                
            
        
    

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" "[email protected]"
$ 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 "[email protected]"
$ chmod +x ng
$ ./ng --version
    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
           |___/
Angular CLI: 6.0.8
Node: 9.11.2
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
$ sed -i -e 's/node_/anode/' .gitignore
$ 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:

    npm-install
    
        npm
    

Install the modules again using

./mvnw generate-resources
and check the result (the versions will differ for you).
$ ./ng version
    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
           |___/
Angular CLI: 7.3.7
Node: 9.11.2
OS: linux x64
Angular: 7.2.11
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package Version

@angular-devkit/architect 0.13.7 @angular-devkit/build-angular 0.13.7 @angular-devkit/build-optimizer 0.13.7 @angular-devkit/build-webpack 0.13.7 @angular-devkit/core 7.3.7 @angular-devkit/schematics 7.3.7 @angular/cli 7.3.7 @ngtools/webpack 7.3.7 @schematics/angular 7.3.7 @schematics/update 0.13.7 rxjs 6.3.3 typescript 3.2.4 webpack 4.29.0

At this point, the tests work:

$ ./ng e2e
..
[13:59:46] I/direct - Using ChromeDriver directly...
Jasmine started

client App ✓ should display welcome message

Executed 1 of 1 spec SUCCESS in 0.718 sec. [13:59:48] I/launcher - 0 instance(s) of WebDriver still running [13:59:48] I/launcher - chrome #01 passed

and if you add this as well:

    
        npm-build
        
            npm
        
        
            run-script build
        
    

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": "^1.4.9",
...

== 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

https://code.visualstudio.com/[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 https://medium.com/codingthesmartway-com-blog/using-bootstrap-with-angular-c83c3cee3f4a[this blog]):

$ ./npm install [email protected] jquery --save

and update

styles.css
to add the new content:

.styles.css

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 https://angular.io[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:

html

Welcome {{title}}!

Id: {{data.id}}

Message: {{data.content}}

so we are looking for a

data
object in the scope of the component:

.app.component.ts: ```javascript 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 = {}; 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 ```javascript 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: ```java @SpringBootApplication @Controller public class DemoApplication {

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

...

} ```

If you look at the source code https://github.com/dsyer/spring-boot-angular[in Github] you will also notice that there is a test for the backend interaction in

app.component.spec.ts
(thanks to http://blog.ninja-squad.com/2017/07/17/http-client-module/[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.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.