SpringBoot CRUD application with AngularJS

This tutorial will demonstrate how to create a Spring Boot CRUD application using AngularJS as front end.

AngularJS is a Javascript based framework for dynamic web apps. It lets you use HTML as your template language and lets you extend its syntax to express your application’s components clearly and in a concise way. In this tutorial we will combina an Angular JS Controller with a Spring Boot REST Service.

Let’s start from the dependencies needed for this application:




Important: Until Spring Boot version 2.2 the starter spring-boot-starter-web had as dependency the starter spring-boot-starter-validation. In Spring Boot 2.3 the starter spring-boot-starter-validation is NOT a dependency of the starter spring-boot-starter-web anymore so you need to add it explicitly. 

As our application will persist data in an H2 Database, we have added both the spring-boot-starter-data-jpa and the h2 dependencies. Then, we have also included the spring-boot-starter-web that allows us using RESTful applications and Spring MVC.

Let’s start from the Entity class, named Customer:

package com.example.cruddemo.entities;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotBlank;

public class Customer {
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;

  @NotBlank(message = "Name is required")
  private String name;

  @NotBlank(message = "Surname is required")
  private String surname;

  public Customer() {}

  public void setId(long id) {
    this.id = id;

  public long getId() {
    return id;

  public void setName(String name) {
    this.name = name;

  public String getName() {
    return name;

  public String getSurname() {
    return surname;

  public void setSurname(String surname) {
    this.surname = surname;

In order to persist data, we will extend the CrudRepository base class, overriding just the findAll method, as we will return a List of Customer objects (instead of an Iterable set):

package com.example.cruddemo.repositories;

import com.example.cruddemo.entities.Customer;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

public interface CustomerRepository extends CrudRepository<Customer, Long> {
  List<Customer> findAll();

Then, here is our Controller class, which contains a method for each HTTP method:

package com.example.cruddemo.controllers;

import com.example.cruddemo.entities.Customer;
import com.example.cruddemo.repositories.CustomerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RequestMapping(value = "/customers")
public class CustomerController {
  private final CustomerRepository customerRepository;

  public CustomerController(CustomerRepository customerRepository) {
    this.customerRepository = customerRepository;

      method = RequestMethod.GET,
      produces = {"application/json"})
  public @ResponseBody List<Customer> listCustomers() {
    return customerRepository.findAll();

      method = RequestMethod.POST,
      consumes = {"application/json"})
  public @ResponseBody void addCustomer(@RequestBody Customer customer) {

      method = RequestMethod.PUT,
      consumes = {"application/json"})
  public @ResponseBody void updateCustomer(@RequestBody Customer customer) {

  @RequestMapping(method = RequestMethod.DELETE)
  public @ResponseBody void deleteCustomer(@RequestParam("id") Long id) {

Please notice the @ResponseBody annotation which tells a controller that the object returned is automatically serialized into JSON and passed back into the HttpResponse object. If not included, Spring MVC would expect to return the view where the navigation continues.

Finally, an Application class is included to boot our Spring Boot CRUD application:

package com.example.cruddemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

That’s all with the Spring Boot part. Now let’s add an index.html page under src/main/webapp. We will check at first the AngularJS part, then the HTML form:

< script src = "//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js" > < /script>     <script type="text/javascript
">       var app = angular.module("
customerManagement ", []);       angular.module('customerManagement').constant('SERVER_URL','/customers');        
//Controller Part       
app.controller("customerManagementController", function ($scope, $http, SERVER_URL) {
  //Initialize page with default data which is blank in this example
  $scope.customers = [];
  $scope.form = {
    id: -1,
    name: "",
    surname: ""
  //Now load the data from server         
  //HTTP POST/PUT methods for add/edit customers 
  $scope.update = function () {
    var method = "";
    var url = "";
    var data = {};
    if ($scope.form.id == -1) {
      //Id is absent so add customers - POST operation  
      method = "POST";
      url = SERVER_URL;
      data.name = $scope.form.name;
      data.surname = $scope.form.surname;
    } else {
      //If Id is present, it's edit operation - PUT operation
      method = "PUT";
      url = SERVER_URL;
      data.id = $scope.form.id;
      data.name = $scope.form.name;
      data.surname = $scope.form.surname;
      method: method,
      url: url,
      data: angular.toJson(data),
      headers: {
        'Content-Type': 'application/json'
    }).then(_success, _error);
  //HTTP DELETE- delete customer by id
  $scope.remove = function (customer) {
      method: 'DELETE',
      url: SERVER_URL + '?id=' + customer.id
    }).then(_success, _error);
  //In case of edit customers, populate form with customer data 

  $scope.edit = function (customer) {
    $scope.form.name = customer.name;
    $scope.form.surname = customer.surname;
    $scope.form.id = customer.id;

  /* Private Methods */ //HTTP GET- get all customers collection

  function _refreshPageData() {
      method: 'GET',
      url: SERVER_URL
    }).then(function successCallback(response) {
      $scope.customers = response.data;
    }, function errorCallback(response) {

  function _success(response) {

  function _error(response) {
    alert(response.data.message || response.statusText);

  //Clear the form         

  function _clearForm() {
    $scope.form.name = "";
    $scope.form.surname = "";
    $scope.form.id = -1;
}); < /script>

As you can see from above, we have created a customerManagementController with a set of functions to handle the HTTP GET, POST, PUT and DELETE functions, passing as argument the HTML data in JSON format. Here is the HTML form contained:

<?xml version="1.0" encoding="UTF-8"?><div class="divTable blueTable">
   <div class="divTableHeading">
      <div class="divTableHead">Customer Name</div>
      <div class="divTableHead">Customer Surname</div>
      <div class="divTableHead">Action</div>
   <div class="divTableRow" ng-repeat="customer in customers">
      <div class="divTableCell">{{ customer.name }}</div>
      <div class="divTableCell">{{ customer.surname }}</div>
      <div class="divTableCell">
         <a ng-click="edit( customer )" class="myButton">Edit</a>
         <a ng-click="remove( customer )" class="myButton">Remove</a>

You can check the full source code for this example at the bottom of this article.

Here is our project tree:

├── main
│   ├── java
│   │   └── com
│   │       └── example
│   │           └── cruddemo
│   │               ├── controllers
│   │               │   └── CustomerController.java
│   │               ├── DemoApplication.java
│   │               ├── entities
│   │               │   └── Customer.java
│   │               └── repositories
│   │                   └── CustomerRepository.java
│   ├── resources
│   │   └── application.properties
│   └── webapp
│       ├── index.html
│       └── stylesheet.css
└── test
    └── java
        └── com
            └── example
                └── cruddemo

Build your Spring Boot CRUD application with:

mvn clean install spring-boot:run 

And finally, here is your AngularJS Spring Boot CRUD application in action:

spring boot angularjs CRUD tutorial

Source code for the AngularJS Spring Boot CRUD application: https://github.com/fmarchioni/masterspringboot/tree/master/crud/spring-crud-angular/angulardemo