Spring Feign Client HTTP Request Example

In this tutorial you will learn how to use Declarative REST Client Feign to make HTTP Requests RESTful Web Services. You can use Feign client to make HTTP Requests to a registered with Eureka Discovery Service Microservice or to an external RESTful Web Service.

Creating New Spring Boot Project

To demonstrate how Feign client works I will create a very simple Spring Boot project and will make it work as a RESTful Web Service. I will then create a new Feign client and use it in this Spring Boot project to make HTTP Requests. If you do already have a project, then you do not need to create a new one. So feel free to skip this step. Otherwise to create a new Spring Boot project please following these steps: Creating a Simple Web Service Project with Spring Boot.

Adding POM.XML Dependencies

To be able to use Spring Feign client in your Spring Boot project you will need to add the following two dependencies:

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

We need to add Ribbon dependency as well because Feign client is load balanced.

Here is my complete POM.XML

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.appsdeveloperblog.examples.feign</groupId>
    <artifactId>FeignTutorial</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>FeignTutorial</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</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-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Creating Feign Client

To create a new Feign REST Client we need to create a new Java interface and annotated it with @FeignClient annotationNo need to provide implementation for this interface. Spring Framework and Feign will provide an implementation for this interface for us at runtime. Our job is to create an interface and properly annotation it with some additional configuration. For example:

package com.appsdeveloperblog.examples.feign;

import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name="TodoClient", url="https://jsonplaceholder.typicode.com")
public interface TodoClient {
    @GetMapping(value="/todos",consumes=MediaType.APPLICATION_JSON_VALUE)
    List<TodoModel> getTodos();
}

Where:

@FeignClient(name=””, url=””) – To make send HTTP request to an external RESTful Web Service provide name and base url value. In my example, the HTTP GET request will be sent to https://jsonplaceholder.typicode.com which is a publicly available web service developers can use to test their web services.

@GetMapping(value=”/todos”,consumes=MediaType.APPLICATION_JSON_VALUE) – here we specify the this is going to be an HTTP GET request to a /todos web service URL endpoint and that as a response we expect JSON representation of a requested resource.

List<TodoModel> getTodos();  – The name of this method signature is not important. What is important is the signature of return type. This method will return a list of TodoModel objects. TodoModel is a Java class which we need to create to model the requested resource. This Java class will be user when a returned JSON representation of the resource will be converted from JSON into Java object.

The above Feign client will send HTTP Get request to the following url https://jsonplaceholder.typicode.com/todos. A response will be a JSON Array of JSON objects. For example:

[
  {"userId":"1","id":1,"title":"delectus aut autem","completed":false},
  {"userId":"1","id":2,"title":"quis ut nam facilis et officia qui","completed":false},
  {"userId":"1","id":3,"title":"fugiat veniam minus","completed":false},
  {"userId":"1","id":4,"title":"et porro tempora","completed":true}
]

We now need to create a TodoModel class for this JSON array to be properly converted into an Array of TodoModel objects.

package com.appsdeveloperblog.examples.feign;

public class TodoModel {

    private String userId;
    private int id;
    private String title;
    private boolean completed;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public boolean isCompleted() {
        return completed;
    }

    public void setCompleted(boolean completed) {
        this.completed = completed;
    }
}

Using Feign REST Client

Now let’s see how we can Autowire Feign Rest client into our code and use it. I will create a RestController with only one method which makes use of FeignClient.

package com.appsdeveloperblog.examples.feign;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/todos")
public class TodoController {
    
    @Autowired
    TodoClient todoClient;
    
    @GetMapping()
    public List<TodoModel> getTodos()
    {
        return todoClient.getTodos();
    }
    
}

To use Feign client you will need to Autowire it to your Controller class or a Service method. In the example above TodoClient is being Autowired to my RestController. Remember that we do not need tot provide implementation for our TodoClient interface. Implementation is provided by the Framework.

Once the REST client is autowired, we can simply call its methods.

The @EnableFeignClients Annotation

One last very important moment. For all of it to work we need two Enable Feign Clients in our application and to do that we need to use the @EnableFeignClients annotation next to a @SpringBootApplication annotation. For example:

package com.appsdeveloperblog.examples.feign;

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

@SpringBootApplication
@EnableFeignClients
public class FeignTutorialApplication {

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

}

And this is it.

I hope this tutorial was helpful for you. To learn more about Spring Cloud checkout our my other tutorials and have a look at the below list of online video courses that teach Spring Cloud.