In the previous article, we learned how to create a eureka server and how to register client services to the service registry.

Before starting, go through the previous article to understand how to register a service into the eureka server.

In this article, we will learn different ways of looking up for the registered services from the eureka server registry.

Using EurekaClient for service discovery

We will create two services with the service name “my-client” and “my-client-2“. We consume the endpoint “/call-me” located in “my-client” service from “my-client-2” using service discovery.

With this approach, we will have a EurekaClient instance. We use this instance to get the available instance from the eureka service registry. Then we call the “call-me” endpoint with the help of RestTemplate instance.

Create a eureka client application by adding the spring-cloud-starter-netflix-eureka-client dependency. Also, add spring-boot-starter-web dependency to the application.

With STS IDE we can choose the dependencies easily as shown below.

eureka-client-example

Update the spring boot application class file with the code given below.

We have added @EnableEurekaClient annotation to register this service with the eureka server for service discovery.

We have also added @RestController annotation along with a @GetMapping annotation to expose “/call-me” endpoint.

@SpringBootApplication
@EnableEurekaClient
@RestController
public class SpringBootEurekaClientApplication {

	@GetMapping("/call-me")
	public String method() {
		return "You are calling me through service discovery!!";
	}
	
	public static void main(String[] args) {
		SpringApplication.run(SpringBootEurekaClientApplication.class, args);
	}
}

Add the property “spring.application.name” to the “application.properties” file. This property registers this service with the name “my-client” into the eureka server.

spring.application.name=my-client

Run the eureka client service with different port numbers. We can use runtime VM arguments to pass the server port numbers while starting the application.

With STS, we can use: right-click on project > Run As > Run Configurations > and set the -Dserver.port parameter as shown below.

running spring boot application on different ports

Access the eureka server dashboard. We should be able to observe registered instances of my-client service on the dashboard.

In the below image we have three instances of my-client service registered with port numbers 8080, 8081 and 8082.

registered clients on eureka server

Create service consumer

Now create another eureka client service similarly. This service will consume the “my-client” service.

Add the following properties into the application.properties of newly created service.

server.port=8090
spring.application.name=my-client-2

This service will run on 8090 port and also register itself with the application name “my-client-2“.

Update the spring boot application class with the following code.

The @EnableEurekaClient annotation registers this service into the eureka server for service discovery. This is not a necessary step though in our example, as we are using this service to only consume the “my-client” service.

We have created a RestTemplate bean. We have used this bean to invoke the “my-client” service’s “/call-me” endpoint.

We have added @Restcontroller and exposed “/call-eureka-client” endpoint. This endpoint prints the discovered service instance URL along with the response message returned from the restTemplate call.

Inside this method, we have used the EurekaClient instance, which is injected using @Autowired annotation. This instance provides various details about available registered service instances.

In our example, we have got the “InstanceInfo of our registered service passing the service name “my-service“.

From the “instanceInfo” object, we are getting the base URL of the registered service and forming the actual service URL.

@SpringBootApplication
@EnableEurekaClient
@RestController
public class SpringBootEurekaClient2Application {

	@Autowired
	private EurekaClient eurekaClient;

	@Bean
	public RestTemplate RestTemplate() {
		return new RestTemplate();
	}

	@Autowired
	private RestTemplate restTemplate;

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

	@GetMapping("/call-eureka-client")
	public String method() {

		InstanceInfo instance = eurekaClient.getNextServerFromEureka("my-client", false);
		String response = restTemplate.getForObject(instance.getHomePageUrl() + "/call-me", String.class);
		return "Instance called is : " + instance.getHomePageUrl() + " <br/><br/> And Response : " + response;
	}
}

Start the service. We should be able to see the service registered on the eureka dashboard.

Services registered on eureka server

Access the service endpoint “/call-eureka-client” from the browser.

We should be able to access the “my-client” endpoint internally. We will also get the instance discovered by EurekaClient.

We can notice the discovered instance is different every time, by refreshing the page.

service discovery example
service discovery example
service discovery example

Congratulation!!. 🙂 We have successfully implemented service discovery with EurekaClient.

Service discovery with Ribbon backed RestTemplate

Update my-client service with following changes.

We have modified a little code in my-client service. We are reading the application instance’s port number and returning it along with the response.

@SpringBootApplication
@EnableEurekaClient
@RestController
public class SpringBootEurekaClientApplication {

	@Value("${server.port}")
	private String serverPort;
	
	@GetMapping("/call-me")
	public String method() {
		return "You are calling me through service discovery!! with server port : " + serverPort;
	}

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

We have updated my-client-2 service too.

Here, we are creating a RestTemplate bean along with @LoadBalanced annotation. This annotation indicates that RestTemplate should use a RibbonLoadBalancerClient for interacting with other services.

@SpringBootApplication
@EnableEurekaClient
@RestController
public class SpringBootEurekaClient2Application {

	@Bean
	@LoadBalanced
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}

	@Autowired
	private RestTemplate restTemplate;

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

	@GetMapping("/call-eureka-client")
	public String method() {

		String response = restTemplate.getForObject("http://my-client/call-me/", String.class);
		return "Response : " + response;
	}
}

In the above code notice that we are using the restTemplate.getForObject() method with the URL http://my-client/call-me/. Here, my-client is the service id of the eureka client, which we are calling from my-service-2.

The below images show the ribbon backed service discovery application output.

Ribbon load balance the requests and passes requests to available instances of the registered eureka client in a round-robin fashion.

Eureka load balanced resttemplate example
Eureka load balanced resttemplate example
Eureka load balanced resttemplate example

That’s it. The explained code is available on Github.

Service discovery with FeignClient

We can use Netflix’s feign client as an alternative to the spring ribbon backed rest template.

Let us see how to use Netflix’s feign client library to call our service.

Add spring-cloud-starter-openfeign dependency to the pom.xml file.

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

Enable feign client library by adding the annotation @EnableFeignClients to spring boot application class.

@SpringBootApplication
@EnableFeignClients
@RestController
public class SpringBootFeignClientExampleApplication {

	//spring boot starter main method
}

While using the feign client, we create a Java interface and then use annotations to map the registered eureka service.

Spring dynamically creates a proxy class that will be used to invoke the service.

Let us create a Java interface with the name ‘MyServiceFeignClient‘ as given below.

@FeignClient("my-client")
public interface MyServiceFeignClient {

	@GetMapping("/call-me")
	public String method();
}

@FeignClient annotation is used to set the eureka service’s application Id, which we are going to invoke. my-client is our eureka service invoked by this feign client template.

The method defined here is the same method present in my-client service.

We can use the feign client to call eureka service by auto-wiring it to our application.

Below is the complete code with the rest endpoint.

@SpringBootApplication
@EnableFeignClients
@RestController
public class SpringBootFeignClientExampleApplication {

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

	@Autowired
	MyServiceFeignClient myServiceFeignClient;

	@GetMapping("/call-eureka-client")
	public String method() {

		String response = myServiceFeignClient.method();
		return "Response : " + response;
	}
}

That’s all.! 🙂 Run the eureka server, my-client service instances, and feign client service.

We should be able to invoke the my-client service from feign client service now.

Feign client example spring boot

That’s it. The explained code is available on Github.

Conclusion

In this article, we learned different ways of consuming a registered eureka service.

We learned how to use EurekaClient, how to use ribbon backed RestTemplate and finally, how to use FeignClient for service discovery.

You may also interested in