Feign is a declarative rest client. It makes writing Rest webservice clients easier. Before proceeding a quick note on declarative programming is given below.
“Declarative programming is a high level programming concept in which we just need to state what the desired result or outcome is. It is the opposite to imperative programming where we need to specify the logic in statements.”
To create a feign client all we need to do is to create an interface and annotate it. Before doing that lets take a quick look on the Rest Web service that we are going to call using Feign. The url of the service is http://localhost:8081/greeting/{id}
. It also needs a request header for request id. It returns a String built using the text block introduced in Java 15.
@RestController
public class RestService {
@GetMapping("/greeting/{id}")
public String sayGreeting(@PathVariable("id") int greetingId,
@RequestHeader("requestId") String requestId){
return """
Greeting number: %s Hello, how are you ?
Request id is: %s
""".formatted(greetingId, requestId);
}
}
Feign Client:
Add the below dependency to create a Feign client.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Create an interface and annotate it with @FeignClient
. Pass an arbitrary name and the url
is taken from application.properties (or) application.yml. Then create a method and annotate it with @RequestMapping
specifying the request method as GET
and the resource path. It takes two parameters. One for path variable and one for request header. Add @EnableFeignClients
annotation to the SpringBootApplication class.
@FeignClient(name="greetingClient", url="${serviceUrl}")
public interface SampleFeignClient {
@RequestMapping(method= RequestMethod.GET, value="/greeting/{greetingId}")
String getGreeting(@PathVariable("greetingId") int greetingId,
@RequestHeader("requestId") String requestId);
}
application.properties
serviceUrl=http://localhost:8081
Now we are all set to call the Rest webservice. Note @EnableFeignClients
annotation has been added. Then the webservice is called using the CommandLineRunner. The path variable greetingId and the requestId are passed as parameters.
@SpringBootApplication
@EnableFeignClients
public class FeignclientApplication {
public static void main(String[] args) {
SpringApplication.run(FeignclientApplication.class, args);
}
@Bean
public CommandLineRunner callService(SampleFeignClient sampleFeignClient){
return (args) -> {
System.out.println(sampleFeignClient.getGreeting(1, UUID.randomUUID().toString()));
};
}
}
Here is the output:
Greeting number: 1 Hello, how are you ?
Request id is: 2e614991-944e-4f04-9b5d-0f2061e8f48f
How to log the HTTP request and response for a Feign Client ?
All we need to do is to add the below configs to application.yml to log the http request and response for a feign client.
#Here SampleFeignClient is the interface name. You can also place this in #logback xml.
logging.level.com.jsession4d.feignclient.SampleFeignClient: DEBUG
feign:
client:
config:
greetingClient:
loggerLevel: FULL
The details of the above configs are provided below:
First the property logging.level.com.jsession4d.feignclient.SampleFeignClient
should be set to DEBUG
. Here com.jsession4d.feignclient.SampleFeignClient
is the full name of the FeignClient interface that we created.
Next, the property feign.client.config.greetingClient.loggerLevel is set to FULL.
Here greetingClient is the FeignClient name that we created. To apply the loggerLevel for all feign clients replace greetingClient
to default
.
There are four loggerLevels available as of this writing. Here we mentioned FULL
. The other 3 available loggerLevels are NONE
, BASIC
, HEADERS
as stated here.
Conclusion:
As we saw, Feign makes creating a REST web service client much easier.