Implementing a REST controller in customer service

Let's implement a CustomerController REST controller to the Customer microservice and expose endpoints for the CRUD operations. The /customer/{customerId} endpoint will simply return the customer details of a given customer ID along with its associated account details. For the account details, it will call another microservice that is already developed and deployed with its host and port number, exposing some endpoints such as /account/customer/{customer}. Let's see the following REST controller class:

package com.dineshonjava.customerservice.controller; 
 
import java.util.ArrayList; 
import java.util.List; 
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.bind.annotation.DeleteMapping; 
import org.springframework.web.bind.annotation.GetMapping; 
import org.springframework.web.bind.annotation.PathVariable; 
import org.springframework.web.bind.annotation.PostMapping; 
import org.springframework.web.bind.annotation.PutMapping; 
import org.springframework.web.bind.annotation.RequestBody; 
import org.springframework.web.bind.annotation.RestController; 
 
import com.dineshonjava.customerservice.domain.Customer; 
import com.dineshonjava.customerservice.repository.CustomerRepository; 
import com.dineshonjava.customerservice.service.AccountService; 
 
@RestController 
public class CustomerController { 
    
   @Autowired 
   CustomerRepository customerRepository; 
    
   @Autowired 
   AccountService accountService;   
    
   @PostMapping(value = "/customer") 
   public Customer save (@RequestBody Customer customer){ 
         return customerRepository.save(customer); 
   } 
    
   @GetMapping(value = "/customer") 
   public Iterable<Customer> all (){ 
         List<Customer> customers = new ArrayList<>(); 
         for(Customer customer : customerRepository.findAll()){ 
            customer.setAccount(accountService.findByCutomer(customer.getCustomerId())); 
         } 
         return customers; 
   } 
    
   @GetMapping(value = "/customer/{customerId}") 
   public Customer findByAccountId (@PathVariable Integer customerId){ 
         Customer customer = customerRepository.findByCustomerId(customerId); 
         customer.setAccount(accountService.findByCutomer(customerId)); 
         return customer; 
   } 
    
   @PutMapping(value = "/customer") 
   public Customer update (@RequestBody Customer customer){ 
         return customerRepository.save(customer); 
   } 
    
   @DeleteMapping(value = "/customer") 
   public void delete (@RequestBody Customer customer){ 
         customerRepository.delete(customer); 
   } 
    
}

As you can see, there are two properties that have been injected, AccountService and CustomerRepository. CustomerRepository is used to access the customer data and AccountService is a delegating service for the Account microservice. Let's see how to create an AccountService.java delegate layer to call the Account service:

package com.dineshonjava.customerservice.service; 
 
import java.util.ArrayList; 
import java.util.List; 
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.cloud.client.loadbalancer.LoadBalanced; 
import org.springframework.stereotype.Service; 
import org.springframework.web.client.RestTemplate; 
 
import com.dineshonjava.customerservice.domain.Account; 
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 
 
@Service 
public class AccountServiceImpl implements AccountService { 
    
   @Autowired 
   @LoadBalanced 
   RestTemplate restTemplate; 
    
   @HystrixCommand(fallbackMethod = "defaultAccount") 
   public List<Account> findByCutomer(Integer customer) { 
         return restTemplate.getForObject("http://ACCOUNT-SERVICE/account/customer/{customer}", List.class, customer); 
   } 
    
   private List<Account> defaultAccount(Integer customer) { 
                 List<Account> defaultList = new ArrayList<>(); 
         defaultList.add(new Account(0000, 1.000, 0000, "UNKNOWN                          ACCOUNT TYPE", "UNK", "FALLBACK BANK")); 
                return defaultList; 
           } 
}

In the code for AccountService, we have performed the following steps to enable the Hystrix circuit-breaker:

  1. Account microservice is invoked by the Spring Framework provided by RestTemplate.
  1. Use the @HystrixCommand(fallbackMethod = "defaultAccount") annotation to add the Hystrix command to enable a fallback method, and we will have to add another defaultAccount method with the same signature as the command method has findByCutomer(Integer customer), which will be invoked when the actual Account service will be down.
  2. Add the defaultAccount(Integer customer) fallback method, which will return a default value.

This Hystrix-enabled Customer microservice will use the Account microservice registered with the Eureka registry server. The account REST service will be the same as the one we created in the previous chapters. You can find the complete example on GitHub (https://github.com/PacktPublishing/Mastering-Spring-Boot-2.0).

Let's build and test the customer service.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.131.47