Netflix Feign is a declarative API which simplifies the job of creating REST Clients. As a matter of fact, Feign reduces a lot of boilerplate code to make the HTTP API clients application to access the microservices. You just simply put in an annotated interface, while the actual implementation will be created at the runtime. Let’s see it in action!
Netflix Feign Client
We will be using the basic building blocks from this tutorial: Service discovery with Netflix Eureka and Ribbon Client Load Balancer that is:
- An Eureka Server
- An Eureka Client
So, assumed that the above projects are up and running, let’s create the Netflix Feign project. Open the Command Line and execute:
spring init -n feign-client -dcloud-eureka,cloud-feign,web,thymeleaf
The following dependencies will be added:
<properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies>
Now enable the Eureka Feign by using the @EnableFeignClients annotation in a main Spring Boot application class that is also annotated with the @SpringBootApplication annotation.
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableEurekaClient @EnableFeignClients public class FeignClientApplication { public static void main(String[] args) { SpringApplication.run(FeignClientApplication.class, args); } }
To create a Feign REST client, create an interface and annotate this interface with an annotation provided by the Netflix Feign library. You don’t need to implement this interface in your cloud application to use the microservice. In order to access the service we have to specify the name value on the @FeignClient annotation (it is the logical service name of the microservice. Let’s see the following code for this interface:
package com.example.demo; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient("spring-cloud-eureka-client") public interface HelloServiceClient { @GetMapping("/hello") String sayHello(); }
We will then create a REST service that can be reached at “/hello-feign”:
package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; @Controller public class HelloWebController { @Autowired HelloServiceClient helloServiceClient; @GetMapping("/hello-feign") String sayHello(ModelMap model) { model.put("message", helloServiceClient.sayHello()); return "hello"; } }
This Controller returns to the hello.html page which prints the “message” output. Include the following hello.html page:
<html xmlns:th="http://www.thymeleaf.org"> <body> <h2 th:text="${message}"></h2> </body> </html>
Now let’s add the application.yml configuration file for this client application as follows:
spring: application: name: spring-cloud-feign-client server: port: 8080 eureka: client: service-url: default-zone: ${EUREKA_URI:http://localhost:8761/eureka} instance: prefer-ip-address: true
Start the application. You should see on your Console that the service was registered:
2019-09-06 09:36:35.658 INFO 16033 --- [ main] com.netflix.discovery.DiscoveryClient : Saw local status change event StatusChangeEvent [timestamp=1567755395658, current=UP, previous=STARTING] 2019-09-06 09:36:35.660 INFO 16033 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_SPRING-CLOUD-FEIGN-CLIENT/192.168.1.5:spring-cloud-feign-client:8080: registering service... 2019-09-06 09:36:35.705 INFO 16033 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_SPRING-CLOUD-FEIGN-CLIENT/192.168.1.5:spring-cloud-feign-client:8080 - registration status: 204 2019-09-06 09:36:35.713 INFO 16033 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 201
If you browse to http://localhost:8761 to view the Eureka dashboard you should see the Client that has been discovered:
Now request the “http://localhost:8080/hello-feign” endpoint:
As you can see from the Console, the request was successfully routed to the Eureka Client:
2019-09-06 09:36:47.966 INFO 16033 --- [nio-8080-exec-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client spring-cloud-eureka-client initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=spring-cloud-eureka-client,current list of Servers=[192.168.1.5:8180],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:1; Active connections count: 0; Circuit breaker tripped count: 0;Active connections per server: 0.0;] },Server stats: [[Server:192.168.1.5:8180; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 01:00:00 CET 1970; First connection made: Thu Jan 01 01:00:00 CET 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0] ]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@21f50c89
Congrats! You just managed to run your an Feign Client application by which you can easily locate and consume the REST service, even when the location changes. Client.
Source code for this tutorial: https://github.com/fmarchioni/masterspringboot/tree/master/cloud/eureka