Angular + Spring Boot REST API Example Tutorial

In this tutorial, we will create a very simple “single page application” using Angular 10 as the front end and Spring boot as the backend.

Angular is a platform and framework for building single-page client applications using HTML and TypeScript. Angular is written in TypeScript. 

Spring boot is popular to develop RESTFul web services and microservices.

Learn spring boot at https://www.javaguides.net/p/spring-boot-tutorial.html

Prerequisites

  • Basic familiarity with HTML & CSS
  • Basic knowledge of JavaScript and programming
  • Spring Boot Basics
  • Angular basics
  • Node.js and npm installed globally

What we will build?

We will build two projects:
  1. sprintboot-backend (server) – To develop REST API
  2. angular-frontend (client) – Consume REST API

Video

You can watch this tutorial on my YouTube channel at 

Develop Spring Boot Backend Application

We will use Spring Data JPA to develop the repository layer and we use the H2 in-memory database to store the data.

Step1: Create a Spring Boot Application

There are many ways to create a Spring Boot application. You can refer to the below articles to create a Spring Boot application.

Step 2: Add Maven dependencies

<?xml version="1.0" encoding="UTF-8"?>
<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/>
        <!-- lookup parent from repository -->
    </parent>
    <groupId>net.javaguides</groupId>
    <artifactId>springboot-backend</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-backend</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Step 3: Create JPA Entity - User.java

Create a new package called model inside net.javaguides.springboot package and then create the User class inside model package with the following contents -
package net.javaguides.springboot.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    private String email;

    public User() {

    }

    public User(String firstName, String lastName, String email) {
        super();
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
}

Step 4: Create Spring Data JPA Repository - UserRepository.java

Create a new package called repository inside net.javaguides.springboot package and then create the following interface inside the repository package -
package net.javaguides.springboot.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import net.javaguides.springboot.model.User;

@Repository
public interface UserRepository extends JpaRepository<User, Long>{

}

Step 5: Spring Controller with REST API - /api/users

Let's create a UserController class and add the following code to it:
package net.javaguides.springboot.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import net.javaguides.springboot.model.User;
import net.javaguides.springboot.repository.UserRepository;

@CrossOrigin(origins = "http://localhost:3000")
@RestController
@RequestMapping("api/")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("users")
    public List < User > getUsers() {
        return this.userRepository.findAll();
    }
}
Note that we have added the below line of code to avoid CORS issues:
@CrossOrigin(origins = "http://localhost:3000")

Step 6: Run Spring Boot Application and Test Rest API

Let's insert a few records in the users table while application startup.
Let's run this spring boot application from IDE -> Right-click -> Run As -> Java Application:
package net.javaguides.springboot;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import net.javaguides.springboot.model.User;
import net.javaguides.springboot.repository.UserRepository;

@SpringBootApplication
public class SpringbootBackendApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootBackendApplication.class, args);
    }

    @Autowired
    private UserRepository userRepository;

    @Override
    public void run(String...args) throws Exception {
        this.userRepository.save(new User("Ramesh", "Fadatare", "ramesh@gmail.com"));
        this.userRepository.save(new User("Tom", "Cruise", "tom@gmail.com"));
        this.userRepository.save(new User("Tony", "Stark", "tony@gmail.com"));
    }
}
Hit this "http://localhost:8080/api/users" link in a browser will popular list of users as JSON:
[{"id":1,"firstName":"Ramesh","lastName":"Fadatare","email":"ramesh@gmail.com"},{"id":2,"firstName":"Tom","lastName":"Cruise","email":"tom@gmail.com"},{"id":3,"firstName":"Tony","lastName":"Stark","email":"tony@gmail.com"}]

Build React JS Frontend Application

With our demo Spring Boot application up and running, let's now create a simple Angular application, capable of consuming the REST controller API.
Let's go ahead and create an Angular application to consume /api/users REST API.
I assume that you have installed Node.js. Now, we need to check the Node.js and NPM versions. Open the terminal or Node command line then type these commands.
C:\Angular>node -v
v10.15.3

C:\Angular>npm -v
6.9.0

Install the latest version of Angular CLI 10

To install or update Angular 10 CLI, type this command in the terminal:
npm install -g @angular/cli
Note that we are installing Angular CLI 10.

Create an Angular 10 App using Angular CLI 10

The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications.
If you are new to Angular CLI then check out official documentation at https://cli.angular.io.
Let's use the below command to generate an Angular 9 Client application. We name this project as "angular-frontend".
ng new angular-frontend
Let's create a User angular component.

Create Component using Angular CLI

Let's auto-generate the component using Angular CLI. Change your project directory to angular-frontend\src\app and run the following commands:
– ng g c user

Create a User Model (TypeScript)

Path - src/app/user.ts
Let's create a new file user.ts inside src/app folder and add the following code to it -
export class User {
    id: number;
    firstName: string;
    lastName: string;
    email: string;
}

UserService

Path - src/app/user.service.ts

Let's create UserService class using Angular CLI:
- ng g s user
The UserService will be used to get the data from the backend by calling spring boot APIs. Update the user.service.ts file inside src/app directory with the following code to it -

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { User } from './user';

@Injectable({
  providedIn: 'root'
})
export class UserService {

  private baseUrl = "http://localhost:8080/api/users";

  constructor(private http: HttpClient) { }

  getUsers(): Observable<User[]>{
    return this.http.get<User[]>(`${this.baseUrl}`);
  }
}

User Component

Path - src/app/user/user.component.ts
We have created UserComponent using Angular CLI to display a list of users. Open UserComponent and add the following code to it -
import { Component, OnInit } from '@angular/core';
import {UserService} from '../user.service'
import { User } from '../user';

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {

  users: User[];
  constructor(private userService: UserService) { }

  ngOnInit(): void {
    this.userService.getUsers().subscribe((data: User[]) => {
      console.log(data);
      this.users = data;
    });
  }
}

UserComponent Template

Path - src/app/user/user.component.html 
Add user.component.html file with the following code to it -
<div class ="container">
    <div class = "card">
        <h3 class="text-center"> Users List</h3>
        <div class = "card-body">
            <table class="table table-striped">
                <thead>
                    <th>Id</th>
                    <th> First Name</th>
                    <th> Last Name</th>
                    <th> Email </th>
                </thead>
                <tbody>
                    <tr *ngFor = "let user of users">
                        <td> {{ user.id}}</td>
                        <td> {{ user.firstName}}</td>
                        <td> {{ user.lastName}}</td>
                        <td> {{ user.email}}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

The Angular Application's Entry Point

If we look inside the angular-frontend folder, we'll see that Angular CLI has effectively created an entire project for us.

Angular's application files use TypeScript, a typed superset of JavaScript that compiles to plain JavaScript. However, the entry point of any Angular application is a plain old index.html file.

Let's edit this file, as follows:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AngularFrontend</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>
<body>
  <app-root></app-root>
</body>
</html>

Note that we have added bootstrap 4 and <app-root> is the root selector that Angular uses for rendering the application's root component.

The app.component.ts Root Component

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'angular-frontend';
}

AppModule 

Path: /src/app/app.module.ts
Defines the root module, named AppModule, that tells Angular how to assemble the application. Initially declares only the AppComponent. As you add more components to the app, they must be declared here.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from  '@angular/common/http';
import { AppComponent } from './app.component';
import { UserComponent } from './user/user.component';

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

Main (Bootstrap) File

Path: /src/main.ts
The main file is the entry point used by angular to launch and bootstrap the application.
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));

Running Angular 10 Client Application

Let's run the above developed Angular App with a command:
ng serve
By default, the Angular app runs on 4200 port but you can change the default port with the following command:
ng serve --port 4201

Demo


Hit http://localhost:4200 link in a browser will host this Angular App.

You can check out the below video for a complete demo of this example project:

Further Readings

Comments