diff --git a/spring-security-rest/pom.xml b/spring-security-rest/pom.xml
index 48791a83c1..5973f8fa5e 100644
--- a/spring-security-rest/pom.xml
+++ b/spring-security-rest/pom.xml
@@ -76,6 +76,14 @@
spring-webmvc
${org.springframework.version}
+
+
+
+
+ org.springframework.hateoas
+ spring-hateoas
+ 0.19.0.RELEASE
+
@@ -329,4 +337,4 @@
-
\ No newline at end of file
+
diff --git a/spring-security-rest/src/main/java/org/baeldung/persistence/model/Customer.java b/spring-security-rest/src/main/java/org/baeldung/persistence/model/Customer.java
new file mode 100644
index 0000000000..b302ec057a
--- /dev/null
+++ b/spring-security-rest/src/main/java/org/baeldung/persistence/model/Customer.java
@@ -0,0 +1,60 @@
+package org.baeldung.persistence.model;
+
+import java.util.Map;
+
+import org.springframework.hateoas.ResourceSupport;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+
+@JsonInclude(Include.NON_NULL)
+public class Customer extends ResourceSupport {
+ private String customerId;
+ private String customerName;
+ private String companyName;
+ private Map orders;
+
+ public Customer() {
+ super();
+ }
+
+ public Customer(final String customerId, final String customerName, final String companyName) {
+ super();
+ this.customerId = customerId;
+ this.customerName = customerName;
+ this.companyName = companyName;
+ }
+
+ public String getCustomerId() {
+ return customerId;
+ }
+
+ public void setCustomerId(final String customerId) {
+ this.customerId = customerId;
+ }
+
+ public String getCustomerName() {
+ return customerName;
+ }
+
+ public void setCustomerName(final String customerName) {
+ this.customerName = customerName;
+ }
+
+ public String getCompanyName() {
+ return companyName;
+ }
+
+ public void setCompanyName(final String companyName) {
+ this.companyName = companyName;
+ }
+
+ public Map getOrders() {
+ return orders;
+ }
+
+ public void setOrders(final Map orders) {
+ this.orders = orders;
+ }
+
+}
diff --git a/spring-security-rest/src/main/java/org/baeldung/persistence/model/Order.java b/spring-security-rest/src/main/java/org/baeldung/persistence/model/Order.java
new file mode 100644
index 0000000000..ca551423e8
--- /dev/null
+++ b/spring-security-rest/src/main/java/org/baeldung/persistence/model/Order.java
@@ -0,0 +1,50 @@
+package org.baeldung.persistence.model;
+
+import org.springframework.hateoas.ResourceSupport;
+
+public class Order extends ResourceSupport {
+ private String orderId;
+ private double price;
+ private int quantity;
+
+ public Order() {
+ super();
+ }
+
+ public Order(final String orderId, final double price, final int quantity) {
+ super();
+ this.orderId = orderId;
+ this.price = price;
+ this.quantity = quantity;
+ }
+
+ public String getOrderId() {
+ return orderId;
+ }
+
+ public void setOrderId(final String orderId) {
+ this.orderId = orderId;
+ }
+
+ public double getPrice() {
+ return price;
+ }
+
+ public void setPrice(final double price) {
+ this.price = price;
+ }
+
+ public int getQuantity() {
+ return quantity;
+ }
+
+ public void setQuantity(final int quantity) {
+ this.quantity = quantity;
+ }
+
+ @Override
+ public String toString() {
+ return "Order [orderId=" + orderId + ", price=" + price + ", quantity=" + quantity + "]";
+ }
+
+}
\ No newline at end of file
diff --git a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java
index 9abe604def..bb51f5fd17 100644
--- a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java
+++ b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java
@@ -43,6 +43,8 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
.and()
.authorizeRequests()
.antMatchers("/api/csrfAttacker*").permitAll()
+ .antMatchers("/api/customers**").permitAll()
+ .antMatchers("/api/customer/**").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.formLogin()
diff --git a/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java b/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java
new file mode 100644
index 0000000000..3a14094440
--- /dev/null
+++ b/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java
@@ -0,0 +1,60 @@
+package org.baeldung.web.controller;
+
+import java.util.List;
+
+import org.baeldung.persistence.model.Customer;
+import org.baeldung.persistence.model.Order;
+import org.baeldung.web.service.CustomerService;
+import org.baeldung.web.service.OrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.hateoas.Link;
+import org.springframework.hateoas.mvc.ControllerLinkBuilder;
+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;
+
+@RestController
+public class CustomerController {
+ @Autowired
+ private CustomerService customerService;
+
+ @Autowired
+ private OrderService orderService;
+
+ @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.GET)
+ public Customer getCustomerById(@PathVariable final String customerId) {
+ return customerService.getCustomerDetail(customerId);
+ }
+
+ @RequestMapping(value = "/customer/{customerId}/{orderId}", method = RequestMethod.GET)
+ public Order getOrderById(@PathVariable final String customerId, @PathVariable final String orderId) {
+ return orderService.getOrderByIdForCustomer(customerId, orderId);
+ }
+
+ @RequestMapping(value = "/customer/{customerId}/orders", method = RequestMethod.GET)
+ public List getOrdersForCustomer(@PathVariable final String customerId) {
+ final List orders = orderService.getAllOrdersForCustomer(customerId);
+ for (final Order order : orders) {
+ final Link selfLink = ControllerLinkBuilder.linkTo(ControllerLinkBuilder.methodOn(CustomerController.class).getOrderById(customerId, order.getOrderId())).withSelfRel();
+ order.add(selfLink);
+ }
+ return orders;
+ }
+
+ @RequestMapping(value = "/customers", method = RequestMethod.GET)
+ public List getAllCustomers() {
+ final List allCustomers = customerService.allCustomers();
+ for (final Customer customer : allCustomers) {
+ final Link selfLink = ControllerLinkBuilder.linkTo(ControllerLinkBuilder.methodOn(CustomerController.class).getCustomerById(customer.getCustomerId())).withSelfRel();
+ customer.add(selfLink);
+ if (orderService.getAllOrdersForCustomer(customer.getCustomerId()).size() > 0) {
+ final Link ordersLink = ControllerLinkBuilder.linkTo(ControllerLinkBuilder.methodOn(CustomerController.class).getOrdersForCustomer(customer.getCustomerId())).withRel("allOrders");
+ customer.add(ordersLink);
+ }
+
+ }
+ return allCustomers;
+ }
+
+}
diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/CustomerService.java b/spring-security-rest/src/main/java/org/baeldung/web/service/CustomerService.java
new file mode 100644
index 0000000000..da016af2d5
--- /dev/null
+++ b/spring-security-rest/src/main/java/org/baeldung/web/service/CustomerService.java
@@ -0,0 +1,13 @@
+package org.baeldung.web.service;
+
+import java.util.List;
+
+import org.baeldung.persistence.model.Customer;
+
+public interface CustomerService {
+
+ List allCustomers();
+
+ Customer getCustomerDetail(final String id);
+
+}
diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/CustomerServiceImpl.java b/spring-security-rest/src/main/java/org/baeldung/web/service/CustomerServiceImpl.java
new file mode 100644
index 0000000000..e179de2554
--- /dev/null
+++ b/spring-security-rest/src/main/java/org/baeldung/web/service/CustomerServiceImpl.java
@@ -0,0 +1,39 @@
+package org.baeldung.web.service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.baeldung.persistence.model.Customer;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CustomerServiceImpl implements CustomerService {
+
+ private HashMap customerMap;
+
+ public CustomerServiceImpl() {
+
+ customerMap = new HashMap<>();
+
+ final Customer customerOne = new Customer("10A", "Jane", "ABC Company");
+ final Customer customerTwo = new Customer("20B", "Bob", "XYZ Company");
+ final Customer customerThree = new Customer("30C", "Tim", "CKV Company");
+
+ customerMap.put("10A", customerOne);
+ customerMap.put("20B", customerTwo);
+ customerMap.put("30C", customerThree);
+
+ }
+
+ @Override
+ public List allCustomers() {
+ return new ArrayList<>(customerMap.values());
+ }
+
+ @Override
+ public Customer getCustomerDetail(final String customerId) {
+ return customerMap.get(customerId);
+ }
+
+}
diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/OrderService.java b/spring-security-rest/src/main/java/org/baeldung/web/service/OrderService.java
new file mode 100644
index 0000000000..9a23488c50
--- /dev/null
+++ b/spring-security-rest/src/main/java/org/baeldung/web/service/OrderService.java
@@ -0,0 +1,13 @@
+package org.baeldung.web.service;
+
+import java.util.List;
+
+import org.baeldung.persistence.model.Order;
+
+public interface OrderService {
+
+ List getAllOrdersForCustomer(String customerId);
+
+ Order getOrderByIdForCustomer(String customerId, String orderId);
+
+}
diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/OrderServiceImpl.java b/spring-security-rest/src/main/java/org/baeldung/web/service/OrderServiceImpl.java
new file mode 100644
index 0000000000..1b8e7b0dde
--- /dev/null
+++ b/spring-security-rest/src/main/java/org/baeldung/web/service/OrderServiceImpl.java
@@ -0,0 +1,64 @@
+package org.baeldung.web.service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.baeldung.persistence.model.Customer;
+import org.baeldung.persistence.model.Order;
+import org.springframework.stereotype.Service;
+
+@Service
+public class OrderServiceImpl implements OrderService {
+
+ private HashMap customerMap;
+ private HashMap customerOneOrderMap;
+ private HashMap customerTwoOrderMap;
+ private HashMap customerThreeOrderMap;
+
+ public OrderServiceImpl() {
+
+ customerMap = new HashMap<>();
+ customerOneOrderMap = new HashMap<>();
+ customerTwoOrderMap = new HashMap<>();
+ customerThreeOrderMap = new HashMap<>();
+
+ customerOneOrderMap.put("001A", new Order("001A", 150.00, 25));
+ customerOneOrderMap.put("002A", new Order("002A", 250.00, 15));
+
+ customerTwoOrderMap.put("002B", new Order("002B", 550.00, 325));
+ customerTwoOrderMap.put("002B", new Order("002B", 450.00, 525));
+
+ final Customer customerOne = new Customer("10A", "Jane", "ABC Company");
+ final Customer customerTwo = new Customer("20B", "Bob", "XYZ Company");
+ final Customer customerThree = new Customer("30C", "Tim", "CKV Company");
+
+ customerOne.setOrders(customerOneOrderMap);
+ customerTwo.setOrders(customerTwoOrderMap);
+ customerThree.setOrders(customerThreeOrderMap);
+ customerMap.put("10A", customerOne);
+ customerMap.put("20B", customerTwo);
+ customerMap.put("30C", customerThree);
+
+ }
+
+ @Override
+ public List getAllOrdersForCustomer(final String customerId) {
+ return new ArrayList<>(customerMap.get(customerId).getOrders().values());
+ }
+
+ @Override
+ public Order getOrderByIdForCustomer(final String customerId, final String orderId) {
+
+ final List orders = (List) customerMap.get(customerId).getOrders().values();
+ Order selectedOrder = null;
+ for (final Order order : orders) {
+ if (order.getId().equals(orderId)) {
+ selectedOrder = order;
+ }
+ }
+ return selectedOrder;
+
+ }
+
+}