Consume Spring HATEOAS Rest API using AngularJS example | Spring Boot

In this tutorial, JavaSampleApproach shows you a Spring Boot example that consumes Spring HATEOAS Rest API using AngularJS.

Related Post:
How to start Spring HATEOAS RestAPI with Spring Boot
Consume Spring HATEOAS Rest API using JQuery Ajax example | Spring Boot
How to integrate Http Angularjs with Spring MVC | Spring Boot

I. Overview

1. Goal

We’ll build a Spring Boot Application in that:
HATEOAS REST Service provides interface for interacting with Customer Database.
– Client calls API by using AngularJS, retrieves and displays:
+ Customer Data (Id, Name) with HATEOAS Links by CustomerId.
+ Order Data for Customer above.

2. Technology

– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.4.RELEASE
– Spring Boot: 1.5.4.RELEASE

3. Project Structure

consume-spring-hateoas-angularjs-structure

HATEOAS REST Service:
+ Customer class extends Spring HATEOAS ResourceSupport.
+ CustomerRepository provides repository methods and custom finder methods for CustomerController to interact with Customer database.
+ CustomerController is a REST Controller which has request mapping methods for RESTful requests such as:
/{id}, /{id}/orders, /getcustomer/{id}
+ Response class defines structure for returned data of HTTP GET.

For more details about creating HATEOAS REST Service, please visit:
How to start Spring HATEOAS RestAPI with Spring Boot

AngularJS:
+ home.jsp contains elements for GET request and display results.
+ controller() and $http.get() GET methods in get.js Javascript file.
+ WebController maps url to home.jsp page.

An example that uses AngularJS HTTP POST/GET:
How to integrate Http Angularjs with Spring MVC | Spring Boot

– Configuration for JSP page and static resources in application.properties
– Dependencies for Spring HATEOAS, WEB MVC, Tomcat in pom.xml

To know how to make application work with JSP page and static resources, please visit:
How to start with JSP page and static resource in Spring Boot

II. Practice

1. Create Spring Boot project

– Using Spring Tool Suite/Eclipse to create Project (WAR packaging), ServletInitializer and SpringBootApplication class will be created automatically.
– Add Dependencies to pom.xml file:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-tomcat</artifactId>
	<scope>provided</scope>
</dependency>

<dependency>
	<groupId>org.apache.tomcat.embed</groupId>
	<artifactId>tomcat-embed-jasper</artifactId>
	<scope>provided</scope>
</dependency>

2. Create Data Model Classes


package com.javasampleapproach.angularhateoas.model;

public class Order {

	private Long id;
	private String name;

	public Order(Long id, String name) {
		this.id = id;
		this.name = name;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

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

}

package com.javasampleapproach.angularhateoas.model;

import java.util.ArrayList;
import java.util.List;

import org.springframework.hateoas.ResourceSupport;

public class Customer extends ResourceSupport {

	private Long customerId;
	private String name;

	private List orders;

	public Customer() {
	}

	public Customer(Long customerId, String name, ArrayList orders) {
		this.customerId = customerId;
		this.name = name;
		this.orders = new ArrayList(orders);
	}

	public Long getCustomerId() {
		return customerId;
	}

	public void setCustomerId(Long customerId) {
		this.customerId = customerId;
	}

	public String getName() {
		return name;
	}

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

	public List getOrders() {
		return orders;
	}

	public void setOrders(List orders) {
		this.orders = orders;
	}

}

3. Create Message Model Class


package com.javasampleapproach.angularhateoas.message;

public class Response {
	private String status;
	private Object data;

	public Response() {

	}

	public Response(String status, Object data) {
		this.status = status;
		this.data = data;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}
}

4. Create Repository Class


package com.javasampleapproach.angularhateoas.repo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.stereotype.Repository;

import com.javasampleapproach.angularhateoas.model.Customer;
import com.javasampleapproach.angularhateoas.model.Order;

@Repository
public class CustomerRepository {

	private final List customers = new ArrayList<>();

	public CustomerRepository() {
		this.customers.add(new Customer(1L, "Jack",
				new ArrayList(Arrays.asList(new Order(1L, "SmartPhone A"), new Order(2L, "Tablet B")))));
		this.customers.add(new Customer(2L, "Adam",
				new ArrayList(Arrays.asList(new Order(3L, "SmartPhone C"), new Order(4L, "Tablet D")))));
		this.customers.add(new Customer(3L, "Kim",
				new ArrayList(Arrays.asList(new Order(5L, "SmartPhone E"), new Order(6L, "Tablet F")))));
	}

	public List findAll() {
		return this.customers;
	}

	public Customer findOne(Long id) {

		for (Customer customer : this.customers) {
			if (customer.getCustomerId().equals(id)) {
				return customer;
			}
		}
		return null;
	}
}

5. Create Controller Classes


package com.javasampleapproach.angularhateoas.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.javasampleapproach.angularhateoas.message.Response;
import com.javasampleapproach.angularhateoas.model.Customer;
import com.javasampleapproach.angularhateoas.model.Order;
import com.javasampleapproach.angularhateoas.repo.CustomerRepository;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*;

import java.util.List;

@RestController
public class CustomerController {

	@Autowired
	private CustomerRepository repository;

	@RequestMapping(path = "/{id}")
	public Response getCustomerById(@PathVariable Long id) {

		Customer customer = this.repository.findOne(id);

		Response response = new Response("Done", customer);
		return response;
	}

	@RequestMapping(path = "/{id}/orders")
	public Response getOrdersForCustomer(@PathVariable Long id) {

		List orders = this.repository.findOne(id).getOrders();

		Response response = new Response("Done", orders);
		return response;
	}

	@RequestMapping(value = "/getcustomer/{id}", method = RequestMethod.GET)
	public Response getResource(@PathVariable Long id) {

		Customer customer = this.repository.findOne(id);

		customer.removeLinks();
		customer.add(linkTo(CustomerController.class).slash(customer.getCustomerId()).withSelfRel());
		customer.add(linkTo(methodOn(CustomerController.class).getOrdersForCustomer(customer.getCustomerId()))
				.withRel("allOrders"));

		Response response = new Response("Done", customer);
		return response;
	}
}

package com.javasampleapproach.angularhateoas.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class WebController {

	@RequestMapping("/")
	ModelAndView home(ModelAndView modelAndView) {

		modelAndView.setViewName("home");

		return modelAndView;
	}
}

6. Configuration for JSP Page and Static Resources

Add these lines to application.properties file:


spring.mvc.view.prefix = /WEB-INF/jsps/
spring.mvc.view.suffix = .jsp

7. Add JSP Page and Javascript File

Under src/main/webapp/WEB-INF/jsps folder, add:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
	<title>Spring Boot HATEOAS - POST-GET AJAX Example</title>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
	<script src="/js/get.js"></script>
	<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" />
</head>
<body>
	<div class="container" ng-app="app">
		<h1>AngularJS - consume HATEOAS</h1>      

		<div ng-controller="getcontroller">
			<input type="text" class="form-control" style="width:100px;" ng-model="customerId"/>
	        <br/>
			<button id="btn-id" ng-click="getfunction()">Get Customer</button>

			<p>{{getResultMessage}}</p>

			<div ng-show="showCustomer">
				<h2>Customer Information</h2>
				Id: {{customer.data.customerId}}<br/>
				Name: {{customer.data.name}}<br/>
				Links:
				<ul>
					<li ng-repeat="link in customer.data.links">
						{{link.rel + ": " + link.href}}
					</li>
				</ul>
			</div>

		    <div ng-show="showOrder">
		    	<h2>Order Information</h2>
		    	<ul class="list-group col-md-4">
		    		<li ng-repeat="order in orders.data"><h4 class="list-group-item">
		    			<strong>Order {{$index}}</strong><br/> 
						Id: {{order.id}}<br/>
						Name: {{order.name}}
					</h4></li>
		    	</ul>
		    </div>
		</div>

	</div>
</body>
</html>

For HTTP GET, we use this method:


$http.get(‘/someUrl’, config).then(successCallback, errorCallback);

Under src/main/webapp/js folder, add:


var app = angular.module('app', []);

app.controller('getcontroller', function($scope, $http, $location) {
	
	$scope.showCustomer = false;
	$scope.showOrder = false;

	$scope.getfunction = function() {
		var url = $location.absUrl() + "getcustomer/" + $scope.customerId;
		var orderUrl;

		var config = {
			headers : {
				'Content-Type' : 'application/json;charset=utf-8;'
			}
		}

		$http.get(url, config).then(function(response) {

			if (response.data.status == "Done") {
				$scope.customer = response.data;
				orderUrl = $scope.customer.data.links[1].href;
				$scope.showCustomer = true;

				$http.get(orderUrl, config).then(function(response) {

					if (response.data.status == "Done") {
						$scope.orders = response.data;
						$scope.showOrder = true;
					} else {
						$scope.getResultMessage = "Customer/Order Data Error!";
					}

				}, function(response) {
					$scope.getResultMessage = "Fail!";
				});

			} else {
				$scope.getResultMessage = "Customer Data Error!";
			}

		}, function(response) {
			$scope.getResultMessage = "Fail!";
		});

	}
});

8. Run & Check Result

– Config maven build:
clean install
– Run project with mode Spring Boot App.
– Open Browser, enter URL:
http://localhost:8080/
consume-spring-hateoas-angularjs-request

– Fill customerID & press Get Customer button.
Customer information with Links and Order Information will appear:
consume-spring-hateoas-angularjs-response

III. Source Code

SpringBootAngularHATEOAS



By grokonez | June 16, 2017.

Last updated on April 30, 2021.



Related Posts


2,524 thoughts on “Consume Spring HATEOAS Rest API using AngularJS example | Spring Boot”