In this example I show how to use Spring Cloud / Spring Boot application with Feign. The source code for this is as follows
https://github.com/papicella/SpringBootEmployeeFeignClient
1. Include the required maven dependency for Feign as shown below
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
2. Assuming your going to lookup a service using Service Discovery with Spring Cloud then include this dependency as well, the example below is doing this using Spring Cloud Service Discovery.
<dependency> <groupId>io.pivotal.spring.cloud</groupId> <artifactId>spring-cloud-services-starter-service-registry</artifactId> </dependency>
See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train
3. To enable Feign we simple add the annotation @EnableFeignClients as shown below
package pas.au.scs.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class SpringBootEmployeeFeignClientApplication { public static void main(String[] args) { SpringApplication.run(SpringBootEmployeeFeignClientApplication.class, args); } }
4. Next we have to create an interface to call our service methods. The interface methods must match the service method signatures as shown below. In this example we use Spring Cloud service discovery to find our service and invoke the right implementation method, Feign can do more then just call registered services through spring cloud service discovery BUT this example does that.
EmployeeServiceClient Interface
package pas.au.scs.demo.employee; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import java.util.List; @FeignClient("SPRINGBOOT-EMPLOYEE-SERVICE") public interface EmployeeServiceClient { @RequestMapping(method = RequestMethod.GET, value = "/emps") List<Employee> listEmployees(); }
So what does the actual service method look like?
@RestController public class EmployeeRest { private static Log logger = LogFactory.getLog(EmployeeRest.class); private EmployeeRepository employeeRepository; @Autowired public EmployeeRest(EmployeeRepository employeeRepository) { this.employeeRepository = employeeRepository; } @RequestMapping(value = "/emps", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public List<Employee> listEmployees() { logger.info("REST request to get all Employees"); List<Employee> emps = employeeRepository.findAll(); return emps; } .....
5. It's important to note that the Feign client is calling a service method using Spring Cloud service discovery , the screen shot below shows how it looks inside Pivotal Cloud Foundry when we select out service registry instance and click on Manage
6. Finally we just need to call our service using the Feign client interface and do do that with Autowire as required. In this example below we use a class annotated with @Controller as shown below which then using the returned data to display the results to a web page using Thymeleaf
package pas.au.scs.demo.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import pas.au.scs.demo.employee.EmployeeServiceClient; @Controller public class EmployeeFeignController { Logger logger = LoggerFactory.getLogger(EmployeeFeignController.class); @Autowired private EmployeeServiceClient employeeServiceClient; @RequestMapping(value = "/", method = RequestMethod.GET) public String homePage(Model model) throws Exception { model.addAttribute("employees", employeeServiceClient.listEmployees()); return "employees"; } }
7. The Web page "employees.html" fragment accessing the returned List of employees is as follows.
<div class="col-xs-12"> <table id="example" class="table table-hover table-bordered table-striped table-condensed"> <thead> <tr> <th>Id</th> <th>Name</th> <th>Job</th> <th>Mgr</th> <th>Salary</th> </tr> </thead> <tbody> <tr th:each="employee : ${employees}"> <td th:text="${employee.id}"></td> <td th:text="${employee.name}"></td> <td th:text="${employee.job}"></td> <td th:text="${employee.mgr}"></td> <td th:text="${employee.salary}"></td> </tr> </tbody> </table> </div>
More Information
1. Spring Cloud
http://projects.spring.io/spring-cloud/
2. Declarative REST Client: Feign
http://cloud.spring.io/spring-cloud-netflix/spring-cloud-netflix.html#spring-cloud-feign
No comments:
Post a Comment