Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RestTemplate should be static globally declared?

I am using Java Callable Future in my code. Below is my main code which uses the future and callables -

public class TimeoutThread {

    public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newFixedThreadPool(5);
        Future<String> future = executor.submit(new Task());

        try {
            System.out.println("Started..");
            System.out.println(future.get(3, TimeUnit.SECONDS));
            System.out.println("Finished!");
        } catch (TimeoutException e) {
            System.out.println("Terminated!");
        }

        executor.shutdownNow();
    }
}

Below is my Task class which implements the Callable interface and I need to generate URL depending on the hostname we have and then make a call to SERVERS using RestTemplate. If there is any exception in the first hostname, then I will generate URL for another hostname and I will try making a call.

class Task implements Callable<String> {
    private static RestTemplate restTemplate = new RestTemplate();

    @Override
    public String call() throws Exception {

    //.. some code

    for(String hostname : hostnames)  {
            if(hostname == null) {
                continue;
            }
            try {
                String url = generateURL(hostname);         
                response = restTemplate.getForObject(url, String.class);

                // make a response and then break
                break;

            } catch (Exception ex) {
                ex.printStackTrace(); // use logger
            }
        }
    }
}

So my question should I declare RestTemplate as static global variable? Or it should not be static in this scenario?

like image 356
AKIWEB Avatar asked Jan 15 '14 18:01

AKIWEB


People also ask

Is RestTemplate asynchronous?

RestTemplate uses Java Servlet API and is therefore synchronous and blocking. Conversely, WebClient is asynchronous and will not block the executing thread while waiting for the response to come back.

Is RestTemplate reactive?

No. RestTemplate keeps existing. WebClient is preferrable in these scenarios, i.e. when you want a reactive web client (asynchronous, non-blocking, using Flux/Mono).

Why RestTemplate is deprecated?

RestTemplate provides a synchronous way of consuming Rest services, which means it will block the thread until it receives a response. RestTemplate is deprecated since Spring 5 which means it's not really that future proof. First, we create a Spring Boot project with the spring-boot-starter-web dependency.

What is true about RestTemplate?

The RestTemplate is the central Spring class for client-side HTTP access. Conceptually, it is very similar to the JdbcTemplate, JmsTemplate, and the various other templates found in the Spring Framework and other portfolio projects.


3 Answers

It doesn't matter either way, static or instance.

RestTemplate's methods for making HTTP requests are thread safe so whether you have a RestTemplate instance per Task instance or a shared instance for all Task instances is irrelevant (except for garbage collection).

Personally, I would create the RestTemplate outside the Task class and pass it as an argument to a Task constructor. (Use Inversion of Control whenever possible.)

like image 189
Sotirios Delimanolis Avatar answered Sep 18 '22 23:09

Sotirios Delimanolis


From a concurrency standpoint, it doesn't matter. RestTemplate is thread safe, so a single instance or multiple instances is irrelevant to proper functioning of the program.

But you might want to consider AsyncRestTemplate instead as shown here.

Also, as others mention, you should consider an IoC approach to separate the creation of your REST client from its use. This article by Martin Fowler is the seminal discussion on the topic.

like image 38
Vidya Avatar answered Sep 22 '22 23:09

Vidya


In my particular case I have found some reasons why one might want to have more than one instance of RestTemplate.

The RestTemplate is a way to invoke a remote endpoint, but HTTP integration looks deceivingly simple and when you start finding special scenarios that do not apply to all your API calls is when you realize you need a way to define some settings in a case by case basis.

Examples of such scenarios are the following:

  • We have different teams in the company, and by mistake we didn't agree on the time format we wanted to use in our our models. Now, different APIs from different teams use different time formats which forced us to define different JSON mapper settings for those cases. This may also happen if you have to invoke third party services.
  • Not all the APIs we call have the same service level agreements or behave the same all over the year. In high season some APIs may have to support more traffic, etc. This means that the connection timeout settings may be different for different APIs and sometimes even depending on the requirements. So, settings like connection timeout, read timeout and write timeout may be configured differently depending on the service you're invoking.
  • Perhaps circuit breaker setting, like those of Hytrix, may need to be configured per service, and so having a RestTemplate instance per service allows more ability to configure settings in a case by case basis.
like image 43
Edwin Dalorzo Avatar answered Sep 19 '22 23:09

Edwin Dalorzo