REST-styled APIs are all around us. Many applications need to invoke REST APIs for some or all of their functions. Hence for applications to function gracefully, they need to consume APIs elegantly and consistently.
RestTemplate is a class within the Spring framework that helps us to do just that. In this tutorial, we will understand how to use
RestTemplate for invoking REST APIs of different shapes.
This article is accompanied by a working code example on GitHub.
What is Spring
According to the official documentation,
RestTemplate is a synchronous client to perform HTTP requests.
It is a higher-order API since it performs HTTP requests by using an HTTP client library like the JDK HttpURLConnection, Apache HttpClient, and others.
The HTTP client library takes care of all the low-level details of communication over HTTP while the
RestTemplate adds the capability of transforming the request and response in JSON or XML to Java objects.
RestTemplate uses the class
java.net.HttpURLConnection as the HTTP client. However, we can switch to another HTTP client library which we will see in a later section.
Some Useful Methods of
Before looking at the examples, it will be helpful to take a look at the important methods of the
RestTemplate provides higher-level methods for each of the HTTP methods which make it easy to invoke RESTful services.
The names of most of the methods are based on a naming convention:
- the first part in the name indicates the HTTP method being invoked
- the second part in the name indicates returned element.
For example, the method
getForObject() will perform a GET and return an object.
getForEntity(): executes a GET request and returns an object of
ResponseEntityclass that contains both the status code and the resource as an object.
getForObject(): similar to
getForEntity(), but returns the resource directly.
exchange(): executes a specified HTTP method, such as GET, POST, PUT, etc, and returns a
ResponseEntitycontaining both the HTTP status code and the resource as an object.
execute(): similar to the
exchange()method, but takes additional parameters:
headForHeaders(): executes a HEAD request and returns all HTTP headers for the specified URL.
optionsForAllow(): executes an OPTIONS request and uses the Allow header to return the HTTP methods that are allowed under the specified URL.
delete(): deletes the resources at the given URL using the HTTP DELETE method.
put(): updates a resource for a given URL using the HTTP PUT method.
postForObject(): creates a new resource using HTTP POST method and returns an entity.
postForLocation(): creates a new resource using the HTTP POST method and returns the location of the newly created resource.
For additional information on the methods of
RestTemplate , please refer to the Javadoc.
We will see how to use the above methods of
RestTemplate with the help of some examples in subsequent sections.
Project Setup for Running the Examples
To work with the examples of using
RestTemplate , let us first create a Spring Boot project with the help of the Spring boot Initializr, and then open the project in our favorite IDE. We have added the
web dependency to the Maven
spring-boot-starter-web is a starter for building web applications. This dependency contains a dependency to the
We will use this POJO class
Product in most of the examples:
We also have built a minimal REST web service with the following
The REST web service contains the methods to create, read, update, and delete
product resources and supports the HTTP verbs GET, POST, PUT, and DELETE.
When we run our example, this web service will be available at the endpoint
We will consume all these APIs using
RestTemplate in the following sections.
Making an HTTP GET Request to Obtain the JSON Response
The simplest form of using
RestTemplate is to invoke an HTTP GET request to fetch the response body as a raw JSON string as shown in this example:
Here we are using the
getForEntity() method of the
RestTemplate class to invoke the API and get the response as a JSON string. We need to further work with the JSON response to extract the individual fields with the help of JSON parsing libraries like Jackson.
We prefer to work with raw JSON responses when we are interested only in a small subset of an HTTP response composed of many fields.
Making an HTTP GET Request to Obtain the Response as a POJO
A variation of the earlier method is to get the response as a POJO class. In this case, we need to create a POJO class to map with the API response.
Here also we are calling the
getForEntity() method for receiving the response as a
Instead of using
getForEntity() method, we could have used the
getForObject() method as shown below:
Instead of the
ResponseEntity object, we are directly getting back the response object.
getForObject() looks better at first glance,
getForEntity() returns additional important metadata like the response headers and the HTTP status code in the
Making an HTTP POST Request
After the GET methods, let us look at an example of making a POST request with the
We are invoking an HTTP POST method on a REST API with the
postForObject() method takes the request body in the form of an
HttpEntity class. The
HttpEntity is constructed with the
Product class which is the POJO class representing the HTTP request.
exchange() for POST
In the earlier examples, we saw separate methods for making API calls like
postForObject() for HTTP POST and
getForEntity() for GET.
RestTemplate class has similar methods for other HTTP verbs like PUT, DELETE, and PATCH.
exchange() method in contrast is more generalized and can be used for different HTTP verbs. The HTTP verb is sent as a parameter as shown in this example:
Here we are making the POST request by sending
HttpMethod.POST as a parameter in addition to the request body and the response type POJO.
exchange() for PUT with an Empty Response Body
Here is another example of using the
exchange() for making a PUT request which returns an empty response body:
Here we are sending
HttpMethod.PUT as a parameter to the
exchange() method. Since the REST API returns an empty body, we are using the
Void class to represent the same.
execute() for Downloading Large Files
execute() in contrast to the
exchange() method is the most generalized way to perform a request, with full control over request preparation and response extraction via callback interfaces.
We will use the
execute() method for downloading large files.
execute() method takes a callback parameter for creating the request and a response extractor callback for processing the response as shown in this example:
Here we are sending a request callback and a response callback to the
execute() method. The request callback is used to prepare the HTTP request by setting different HTTP headers like
responseExtractor used here extracts the response and creates a file in a folder in the server.
Invoking APIs with
application/form Type Input
Another class of APIs takes
HTTP form as an input. To call these APIs, we need to set the
Content-Type header to
application/x-www-form-urlencoded in addition to setting the request body. This allows us to send a large query string containing name and value pairs separated by
& to the server.
We send the request in form variables by wrapping them in a
LinkedMultiValueMap object and use this to create the
HttpEntity class as shown in this example:
Here we have sent three form variables
name , and
brand in the request by first adding them to a
MultiValueMap and then wrapping the map in
HttpEntity . After that, we are invoking the
postForEntity() method to get the response in a
Configuring the HTTP Client in
The simplest form of
RestTemplate is created as a new instance of the class with an empty constructor as seen in the examples so far.
As explained earlier,
RestTemplate uses the class
java.net.HttpURLConnection as the HTTP client by default. However, we can switch to a different HTTP client library like Apache HttpComponents, Netty, OkHttp, etc. We do this by calling the
setRequestFactory() method on the class.
In the example below , we are configuring the
RestTemplate to use Apache HttpClient library. For this, we first need to add the client library as a dependency.
Let us add a dependency on the
httpclient module from the Apache HttpComponents project:
Here we can see the dependency on
httpclient added in Our Maven
Next we will configure the HTTP client with settings like connect timeout, socket read timeout, pooled connection limit, idle connection timeout, etc as shown below:
In this example, we have specified the HTTP connection timeout and socket read timeout intervals to 5 seconds. This allows us to fine-tune the behavior of the HTTP connection.
Other than the default
HttpURLConnection and Apache HttpClient, Spring also supports Netty and OkHttp client libraries through the
Attaching an ErrorHandler to
RestTemplate is associated with a default error handler which throws the following exceptions:
- HTTP status 4xx :
- HTTP status 5xx :
- unknown HTTP status :
These exceptions are subclasses of
RestClientResponseException which is a subclass of
RuntimeException . So if we do not catch them they will bubble up to the top layer.
The following is a sample of an error produced by the default error handler when the service responds with an HTTP status of 404:
RestTemplate allows us to attach a custom error handler. Our custom error handler looks like this:
CustomErrorHandler class implements the
ResponseErrorHandler interface. It also uses an error POJO:
RestTemplateError and a runtime exception class
We override two methods of the
handleError() . The error handling logic is in the
handleError() method. In this method, we are extracting the service path and error message from the error response body returned as a JSON with the Jackson ObjectMapper.
The response with our custom error handler looks like this:
The output is more elegant and can be produced in a format compatible with our logging systems for further diagnosis.
RestTemplate in Spring Boot applications, we can use an auto-configured
RestTemplateBuilder to create
RestTemplate instances as shown in this code snippet:
RestTemplateBuilder autoconfigured by Spring is injected in the class and used to attach the
CustomErrorHandler class we created earlier.
MessageConverters to the
REST APIs can serve resources in multiple formats (XML, JSON, etc) to the same URI following a principle called content negotiation. REST clients request for the format they can support by sending the
accept header in the request. Similarly, the
Content-Type header is used to specify the format of the request.
The conversion of objects passed to the methods of
RestTemplate is converted to HTTP requests by instances of
HttpMessageConverter interface. This converter also converts HTTP responses to Java objects.
We can write our converter and register it with
RestTemplate to request specific representations of a resource. In this example, we are requesting the XML representation of the
Here we have set up the
RestTemplate with a message converter
XStreamMarshaller since we are consuming XML representation of the
Comparison with Other HTTP Clients
As briefly mentioned in the beginning
RestTemplate is a higher-level construct which makes use of a lower-level HTTP client.
Starting with Spring 5, the
RestTemplate class is in maintenance mode. The non-blocking
WebClient is provided by the Spring framework as a modern alternative to the
WebClient offers support for both synchronous and asynchronous HTTP requests and streaming scenarios. Therefore,
RestTemplate will be marked as deprecated in a future version of the Spring Framework and will not contain any new functionalities.
RestTemplate is based on a thread-per-request model. Every request to
RestTemplate blocks until the response is received. As a result, applications using
RestTemplate will not scale well with an increasing number of concurrent users.
The official Spring documentation also advocates using
WebClient instead of
RestTemplate is still the preferred choice for applications stuck with an older version(< 5.0) of Spring or those evolving from a substantial legacy codebase.
Here is a list of the major points for a quick reference:
RestTemplateis a synchronous client for making REST API calls over HTTP
RestTemplatehas generalized methods like
exchange()which take the HTTP method as a parameter.
execute()method is most generalized since it takes request and response callbacks which can be used to add more customizations to the request and response processing.
RestTemplatealso has separate methods for making different HTTP methods like
- We have the option of getting the response body in raw JSON format which needs to be further processed with a JSON parser or a structured POJO that can be directly used in the application.
- Request body is sent by wrapping the POJOs in a
RestTemplatecan be customized with an HTTP client library, error handler, and message converter.
- Lastly, calling
RestTemplatemethods results in blocking the request thread till the response is received. Reactive
WebClientis advised to be used for new applications.
You can refer to all the source code used in the article on Github.