Enterprise Java

Making REST Communication Easy with Feign Clients

In this example, we shall show you how to develop a simple Spring Boot Application with a Feign client for consuming a Weather REST service.

Spring Boot is a Java-based framework, which simplifies the building of web and enterprise applications. Spring Boot has an embedded Tomcat, provides ‘starter’ dependencies and no requires the configuration of XMLs.

Feign is a declarative framework developed by Netflix for implementing REST API clients. Feign allows building REST clients declaring and annotating an interface, the actual implementation is provisioned at runtime.

1. Project Environment

This example will be implemented using the following tools:

  1. JDK 1.8.81
  2. IntelliJ 2018.2.2
  3. Spring Boot 2.0.4
  4. Gradle 4.10
  5. Spring Cloud Finchley.SR1

With this information, let’s start!

2. Create a Spring Boot Application

Click on File -> New -> Project

Feign Client - Create a Spring Boot Application
Create a Spring Boot Application – Step 1

Select Spring Initializr and choose the proper JDK version.
Feign Client - Create a Spring Boot Application - Step 2
Create a Spring Boot Application – Step 2

Add a Group and Artifact name. Select Gradle Project and enter a version for your project.
Feign Client - Create a Spring Boot Application - Step 3
Create a Spring Boot Application – Step 3

In the next window select the options:

  • Core -> DevTools
  • Web -> Web
  • Cloud -> Cloud Bootstrap

Feign Client - Create a Spring Boot Application - Step 4
Create a Spring Boot Application – Step 4

Choose a location for the project and clic on Finish button.
Feign Client - Create a Spring Boot Application - Step 5
Create a Spring Boot Application – Step 5

And Voila! You have a Spring Boot Application.
Feign Client - Create a Spring Boot Application - Step 6
Create a Spring Boot Application – Step 6

3. Create a Controller and Start the Application

Create one class named FeignController. Annotate the Java Class as a Controller and implement a GET method that returns a ResponseEntity with dummy data. After, I am going to complete the map with real information.

package com.example.feign.controller;

@RestController
public class FeignController {

    private final IWeatherClient weatherClient;

    @Autowired
    public FeignController(IWeatherClient weatherClient) {
        this.weatherClient = weatherClient;
    }

    @GetMapping(path = "/weather")
    ResponseEntity<Map> getWeather() {
        return ResponseEntity.ok(weatherClient.getWeather().getBody());
    }
}

Edit the file application.properties with the port for deploying the application.

server.port=9090

Finally, run and test the first version of the application.

Feign Client - Test the application
Test the application

4. Feign Client Implementation

Edit build.gradle file and include the next dependencies:

compile('org.springframework.boot:spring-boot-starter-web-services')
compile('org.springframework.cloud:spring-cloud-starter-openfeign')
compile('org.springframework.cloud:spring-cloud-starter-config')

Remember run the build Gradle task.

Feign Client - Run the build Gradle task
Run the build Gradle task

Create one package and one interface. It will be our Feign Client. I have named it IWeatherClient
Feign Client - Create a new class
Create a new class

Annotate the interface as a FeignClient and add one method for getting the weather. The annotation @FeignClient requires that you include the name and URL of the service. In this case, I have chosen datalike name and I have used a property for the URL.

package com.example.feign.feign;

@FeignClient(name = "data", url = "${feign.client.url}")
public interface IWeatherClient {

    @RequestMapping(method = RequestMethod.GET)
    ResponseEntity<Map> getWeather();

}

Add one implementation for the interface. It will be the fallback if something goes wrong invocating the service. In this case, I don’t have a fallback, so I am returning null.

package com.example.feign.feign.imp;

@Component
public class WeatherFallback implements IWeatherClient {

    @Override
    public ResponseEntity



<map> getWeather() {
        return null;
    }

}
</map>

Annotate the main class to enable Feign Clients. The annotation @EnableFeignClients requires that you include the base packages.

package com.example.feign;

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

@SpringBootApplication
@EnableFeignClients(basePackages = {"com.example.feign.feign",
        "com.example.feign.controller"})
public class FeignApplication {

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

Finally, use the feign client in the controller and run again the application.

Feign Client - Result of creating the Feign Client
Result of creating the Feign Client

5. Conclusion

This entry explained how to build a declarative HTTP client using Feign to consume a Weather API. The goal of Feign is reducing the complexity of binding a denominator uniformly with HTTP APIS regardless of restfulness.

6. Download the Project

Download
You can download the full source code of this example here: Feign Example
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
KARL I MILLER
KARL I MILLER
5 years ago

What does this mean?
“… denominator uniformly with HTTP APIS regardless of restfulness”. I see no abstraction in this example that discerns the calls to the spring service as an HTTP API. Can you please explain in English?

Yury Yineth Niño Roa
Yury Yineth Niño Roa
5 years ago
Reply to  KARL I MILLER

This is the definition provided by Netflix: “Feign is a java to http client binder inspired by Retrofit, JAXRS-2.0, and WebSocket. Feign’s first goal was reducing the complexity of binding denominator uniformly to http apis regardless of restfulness.” and considering that Feign is less complex than RestTemplate, for example, when you are binding a client (in this case the denominator) with the service is easier. This fact promotes a RESTful implementation, which should have the six principles: Client-Server, Stateless, Cacheable, Uniform Interface, Layered System and Code on Demand. I think due it is declarative (only require a java interface) it… Read more »

Daniel
Daniel
5 years ago

What’s the deal with those “I”s before interface names?!

Yury Yineth Niño Roa
Yury Yineth Niño Roa
5 years ago
Reply to  Daniel

It is a personal way to write them, but it is not necessary. More, I remember a quote int Clean Code Blook: I prefer to leave interfaces unadorned. Thank you for the comment.

hamid
hamid
4 years ago

a very bad tutorial. lots of errors. please dont write tutorials if you dont have a quality mind of doing it right.

Yury Nino
Yury Nino
4 years ago
Reply to  hamid

Hi, thank you so much for your comment … could you improve it writting what is wrong? … I would really appreciate it :)

Back to top button