Implementation of Feign client without providing Url of service

Posted By Rupesh Sharma | 23-Dec-2018

This blog is in the context to those who have the basic idea of Feign implementation and usage. We know that Feign calls are used to communicate among microservices and sending/receiving data from one service to another. Here we will talk about the better usage of Feign where we just to provide the name of the service from where we either want to receive or send data and rest it will automatically fetch the IP of the service from the registry. Let's look at an example where we want to communicate with a service B using feign in service A. So the code will be like this:

 

package com.example.A.feign;
import org.springframework.http.ResponseEntity;
import feign.Headers;
import feign.RequestLine;
import org.springframework.http.MediaType;

import com.example.A.constant.UrlConstants;

public interface FeignImplementationServiceB {

	@RequestLine("GET " + UrlConstants.ADMIN_ID)
	@Headers({ "Content-Type: " + MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity callToMethodOfServiceB();
}

 

In the example we can see that we haven't provided any URL for the destined service i.e B.Now if we are not providing URL for of the service B then we will fetch the IP of service B from the registry. Below is the generic method that requires the service name and will fetch the instance of the service from the registry and if the service is down, a message will be shown on the console.

 

package com.ezbitex.ordermatching.utils;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Application;
import feign.Feign;
import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;

@Component
public class FeignUtil {

	@Autowired
	EurekaClient eurekaClient;
	@Autowired
	Encoder feingEncoder;
	@Autowired
	Decoder feignDecoder;

	private static Logger logger = LoggerFactory.getLogger(FeignUtil.class);
	public Object getInstanceOfServiceClass(Class serviceClass, String serviceName) {

		Application service = eurekaClient.getApplication(serviceName);
		if (Objects.nonNull(service) && !service.getInstances().isEmpty()) {
			String serviceUri = service.getInstances().get(0).getIPAddr();
			Object serviceClassObject = null;

			serviceClassObject = Feign.builder().encoder(feingEncoder).decoder(feignDecoder).retryer(Retryer.NEVER_RETRY).target(serviceClass,
					serviceUri);			
			return serviceClassObject;

		} else {
			logger.debug("{} Service is currently down. Cannot proceed further ",serviceName);
			return null;
		}
	}
}

 

Now the implementation part. The interface we have created earlier FeignImplementationServiceB will be used here to call the method "callToMethodOfServiceB" of service B to get the data.

 

@Value("${feign.service.name}")
private String serviceName;

	public boolean getDataFromServiceB() {

		ResponseEntity response = null;
		Object obj = feignUtil.getInstanceOfServiceClass(FeignImplementationServiceB.class, serviceName);

		if (Objects.nonNull(obj)) {
			response = ((FeignImplementationServiceB) obj).callToMethodOfServiceB();
			logger.debug("The response is :: {}", response);

		} else {
			logger.debug("Obj is null :::");
			System.exit(0);
		}

 

Here is the descriptive explanation of the better implementation of feign in sending/receiving data from one microservice to another. Hope this will help !!

Request for Proposal

Recaptcha is required.

Sending message..