Search code examples
javaspring-bootresttemplate

RestTemplate: exchange() vs postForEntity() vs execute()


I am working on Rest API using Spring boot and I had to access an application's endpoint. I used RestTemplate for it. I was able to do it using 2 methods,

  • postForEntity():

    responseEntity = 
        restTemplate.postForEntity(uri, httpEntity, ResponseClass.class);
    
  • exchange():

    responseEntity = 
        restTemplate.exchange(uri, HttpMethod.POST, httpEntity, ResponseClass.class);
    

I would like to know the usage and differences of these two methods.

I also see another method execute(). Please shed some light on it. How and when to use it.


Solution

  • The RestTemplate is a very versatile object.

    Let's start with execute, since it's the most generic method:

    execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
            @Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables)
    

    Note the uriVariables can be passed as a Map too.

    execute is designed to be applicable in the highest variety of scenarios possible:

    • The first and second parameters allow any valid combination of URL and method.
    • The request can be modified in a myriad of different ways by passing a custom RequestCallback (a @FunctionalInterface with just one method doWithRequest(ClientHttpRequest request)) before sending it.
    • The response returned from the remote resource can be deserialized in any way necessary by passing a custom ResponseExtractor.

    Compare this with exchange:

    exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
             Class<T> responseType, Object... uriVariables)
    

    There are two major differences here:

    • You can now pass an HttpEntity directly, whereas before it needed to be set manually using the RequestCallback.
    • Deserialization mechanics are provided out of the box by passing the desired response type Class.

    As you can see, this is much more convenient for everyday use.

    Methods like getForEntity and postForEntity are even shorter, easier to understand versions of this:

    getForEntity(String url, Class<T> responseType, Object... uriVariables)
    
    postForEntity(String url, @Nullable Object request, Class<T> responseType,
                  Object... uriVariables)
    

    Notice postForEntity now allows you to POST any Object directly without a wrapper. There is no performance benefit or detriment to using these instead of execute, as they call execute themselves under the hood - it's simply a matter of convenience.