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.

For a step-by-step series of video lessons, please check this page: Spring Boot Microservices and Spring Cloud.

Creating New Spring Boot Project

To demonstrate how Feign client works, I will create a very simple Spring Boot project and 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 follow these steps in this tutorial: Creating a Simple Web Service Project with Spring Boot.

Adding POM.XML Dependencies

To be able to use the 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 also need to add Ribbon dependency 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 annotate it with @FeignClient annotationNo need to provide an implementation for this interface. Spring Framework and Feign will implement this interface for us at runtime. Our job is to create an interface and properly annotate 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 an 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 that 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}
]

Next, we 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 that uses 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 to provide an implementation for our TodoClient interface. Implementation is provided by the Framework.

Once the REST client is injected, 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 to you. To learn more about Spring Cloud, check out my other tutorials and have a look at the below list of online video courses that teach Spring Cloud.


Leave a Reply

Your email address will not be published. Required fields are marked *