Spring Cloud step-by-step (part 5)
Tags: spring, cloud, clouddiscovery, ribbon
Published: 2018-06-28 23:51:58

---
title: Spring Cloud step-by-step (part 5)
published: true
description: Using service discovery in Java code with RestTemplate and Ribbon
tags: spring,cloud,cloud discovery,ribbon
---
This is a continuation of previous blog posts: 
This is a continuation of previous blog posts: 
 - [Spring Cloud step-by-step (part 1)](https://dev.to/piczmar_0/spring-cloud-step-by-step-part-1-1670)
 - [Spring Cloud step-by-step (part 2)](https://dev.to/piczmar_0/spring-cloud-step-by-step-part-2-12o2)
 - [Spring Cloud step-by-step (part 3)](https://dev.to/piczmar_0/spring-cloud-step-by-step-part-3-4jeg)
 - [Spring Cloud step-by-step (part 4)](https://dev.to/piczmar_0/spring-cloud-step-by-step-part-4-l00)

In [previous blog post](https://dev.to/piczmar_0/spring-cloud-step-by-step-part-4-l00) I showed you how to invoke other services using `EurekaClient`, but there is a simpler way.

`RestTemplate` is smart enough to resolve service URI from Eureka server itself.

[Ribbon](https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-ribbon.html) is a client-side load balancer and `SpringTemplate` supports it by simply adding one annotation: `@LoadBalanced`.

Let's create version 2 of Rental Service controller which will look this way:

```java
@RestController
@RequestMapping(path = "/v2")
public class RentalControllerV2 {
    protected String serviceUrl = "http://PRICING-SERVICE";

    private final RestTemplate restTemplate;

    public RentalControllerV2(@Qualifier("ribbon-template") RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @RequestMapping(path = "/rentals/{id}/charges", method = RequestMethod.GET)
    public ResponseEntity getPossibleCharges(@PathVariable("id") String id) {

        ZonedDateTime startTime = ZonedDateTime.now();
        ZonedDateTime endTime = startTime.plus(2, ChronoUnit.DAYS);
        HttpEntity<PriceRequest> request = new HttpEntity<>(
                new PriceRequest("vip", startTime, endTime)
        );
        PriceResponse response = restTemplate.postForObject(serviceUrl + "/v1/prices", request, PriceResponse.class);
        return new ResponseEntity<>(new RentalChargesResponse(response.getPrice()), HttpStatus.OK);
    }
}

```

To enable Ribbon we have to add this property in `bootstrap.yaml` or `application.yaml`
```
ribbon:
  http:
    client:
      enabled: true
```

In the controller above I am injecting `RestTemplate` as a bean named `ribbon-template`.
This is because I wanted to leave two `RestTemplate` beans in the application: one which we use in version 1 controller with native EurekaClient API and another in version 2 controller which is load-balanced `RestTemplate`.


This is how my beans configuration looks like in main class:

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

@Bean("ribbon-template")
@LoadBalanced
public RestTemplate restTemplateWithRibbon() {
	return new RestTemplate();
}
```

And that's it. Start the application and invoke endpoint:


```
curl localhost:8080/v2/rentals/1/charges
```

You will see in logs how Spring is resolving Rental Service URL from service name:

```
2018-06-29 01:11:58.027  INFO 18934 --- [nio-8080-exec-1] c.netflix.config.ChainedDynamicProperty  : Flipping property: PRICING-SERVICE.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2018-06-29 01:11:58.048  INFO 18934 --- [nio-8080-exec-1] c.n.u.concurrent.ShutdownEnabledTimer    : Shutdown hook installed for: NFLoadBalancer-PingTimer-PRICING-SERVICE
2018-06-29 01:11:58.067  INFO 18934 --- [nio-8080-exec-1] c.netflix.loadbalancer.BaseLoadBalancer  : Client: PRICING-SERVICE instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=PRICING-SERVICE,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
2018-06-29 01:11:58.072  INFO 18934 --- [nio-8080-exec-1] c.n.l.DynamicServerListLoadBalancer      : Using serverListUpdater PollingServerListUpdater
2018-06-29 01:11:58.089  INFO 18934 --- [nio-8080-exec-1] c.netflix.config.ChainedDynamicProperty  : Flipping property: PRICING-SERVICE.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2018-06-29 01:11:58.090  INFO 18934 --- [nio-8080-exec-1] c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client PRICING-SERVICE initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=PRICING-SERVICE,current list of Servers=[192.168.43.107:46579],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone;	Instance count:1;	Active connections count: 0;	Circuit breaker tripped count: 0;	Active connections per server: 0.0;]
},Server stats: [[Server:192.168.43.107:46579;	Zone:defaultZone;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 01:00:00 CET 1970;	First connection made: Thu Jan 01 01:00:00 CET 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@fcc5a3d
2018-06-29 01:11:58.131  INFO 18934 --- [nio-8080-exec-1] com.netflix.http4.ConnectionPoolCleaner  : Initializing ConnectionPoolCleaner for NFHttpClient:PRICING-SERVICE
2018-06-29 01:11:59.075  INFO 18934 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: PRICING-SERVICE.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647

```

As usual, source code for this example is on Github [spring-cloud-5](https://github.com/piczmar/spring-cloud-rental/tree/spring-cloud-5) branch.