Skip to the content.

OpenFeign

Declarative REST Client. OpenFeign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations.

Configuration

Step 1: Include dependencies in pom.xml.

...
<properties>
  <java.version>11</java.version>
  <spring-cloud.version>2021.0.7</spring-cloud.version>
</properties>

<dependencies>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>
  ...
</dependencies>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
...

Step 2: Enable Feign clients with @EnableFeignClients annotation in the main class.

package br.com.romulofpaiva.hrpayroll;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients
@SpringBootApplication
public class HrPayrollApplication {

    public static void main(String[] args) {
        SpringApplication.run(HrPayrollApplication.class, args);
    }
}

Step 3: Configure application.properties with the client URL and path.

worker.url=http://localhost:8081
worker.path=workers

Feign Client

Step 1: Create an interface for your Feign Client.

package br.com.romulofpaiva.hrpayroll.clients.hrworker;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "worker", url = "${worker.url}", path = "/${worker.path}")
@Component
public interface WorkerFeignClient {

    @GetMapping(path = "/{id}")
    ResponseEntity<Worker> findById(@PathVariable Long id);

}

Step 2: In the service class, create a variable of the Feign client class type, then call the interface method.

P.S.: In this example, there is an interface WorkerClient that allow us to change the client implementation without change our service class. It’s a design pattern: “program to interfaces, not implementations”.

package br.com.romulofpaiva.hrpayroll.clients.hrworker;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class WorkerClientImpl2 implements WorkerClient {

    @Autowired
    private WorkerFeignClient workerFeignClient;

    @Override
    public Worker findById(Long workerId) {
        return workerFeignClient.findById(workerId).getBody();
    }
}