RestTemplate should be static globally declared?
Solution 1:
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.)
Solution 2:
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.
Solution 3:
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.
Solution 4:
As already said, RestTemplate is thread safe.
But, for unit test, use a static variable will bring to you some problems to mock his calls. So, consider to inject the RestTemplate using the class constructor:
@Service
class LoginService {
private final RestTemplate restTemplate;
public LoginService(final RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
}