skip to content

RestTemplate (Legacy)

RestTemplate is the older template-method client that still fills most existing codebases, configured through RestTemplateBuilder with converters and interceptors. Interviewers ask about its status and what you would migrate to.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is Spring's RestTemplate, and how do you make a simple GET and POST call with it?

level: juniorimportance: must knowfreq 70%

answer

  1. template-method per verb: getForObject/postForEntity/exchange
  2. getForObject=body, getForEntity=ResponseEntity
  3. HttpMessageConverters (Jackson) do JSON
  4. build via RestTemplateBuilder, reuse singleton
  5. maintenance mode since Spring 5 -> RestClient

basics

~10 s

RestTemplate is Spring's synchronous HTTP client for calling REST APIs. Use getForObject(url, Type.class) to GET and deserialize a response, and postForObject/postForEntity(url, body, Type.class) to POST a body and read the reply.

solid answer

~40 s

RestTemplate is Spring's classic synchronous, blocking HTTP client that wraps the plumbing of making a request and converting the response body into a Java object. It exposes template methods per HTTP verb: getForObject/getForEntity, postForObject/postForEntity, put, delete, and the general exchange. getForObject returns just the deserialized body; getForEntity returns a ResponseEntity so you also see status and headers. It uses HttpMessageConverters (Jackson for JSON by default) to marshal bodies. You typically create it once via RestTemplateBuilder (which applies Boot's auto-config) and reuse it — it's thread-safe once configured. Since Spring 5 it's in maintenance mode; new code should prefer RestClient (or WebClient), but RestTemplate is still fully supported and pervasive in existing codebases.

code

java · 23 lines
java
@Service
public class UserClient {

    private final RestTemplate rest;

    public UserClient(RestTemplateBuilder builder) {
        this.rest = builder
            .rootUri("https://api.example.com")
            .connectTimeout(Duration.ofSeconds(2))
            .readTimeout(Duration.ofSeconds(5))
            .build();
    }

    // GET -> deserialized body only
    public User getUser(long id) {
        return rest.getForObject("/users/{id}", User.class, id);
    }

    // POST -> full ResponseEntity (status + headers + body)
    public ResponseEntity<User> create(CreateUser cmd) {
        return rest.postForEntity("/users", cmd, User.class);
    }
}

go deeper

for a junior

Know the verb methods and that getForObject returns the body while getForEntity returns a ResponseEntity.

for a middle

Know RestTemplateBuilder, timeouts, and that Jackson converters deserialize JSON automatically.

for a senior

Emphasize thread-safety/singleton reuse, URI-template encoding, default exception mapping, and maintenance-mode status.

for a principal

Frame RestTemplate within a client strategy: standardize on RestClient for new code, wrap timeouts/pooling/observability, and manage the migration path.

## What RestTemplate is `RestTemplate` (package `org.springframework.web.client`) is Spring's original **synchronous, blocking** HTTP client. "Synchronous/blocking" means the calling thread waits until the HTTP response comes back before continuing. It follows the **template-method pattern**: it hides the repetitive steps of opening a connection, writing the request, reading the response, handling errors, and converting bytes to/from Java objects, exposing convenient one-line methods per HTTP verb. ## Core methods (grouped by verb) - **GET**: `getForObject(url, Class, uriVars...)` returns just the deserialized body; `getForEntity(...)` returns a `ResponseEntity<T>` so you can read status code and headers too. - **POST**: `postForObject(url, requestBody, Class)` returns the body; `postForEntity(...)` returns a `ResponseEntity`; `postForLocation(...)` returns the `Location` header URI. - **PUT/DELETE**: `put(url, body)` and `delete(url)` return `void`. - **exchange(...)**: the fully general method — you pass an `HttpMethod`, an `HttpEntity` (body + headers), and a response type. Use it when you need to set request headers or read a generic type. - **execute(...)**: lowest level, takes callbacks; rarely used directly. ## Deserialization: HttpMessageConverters RestTemplate converts bytes ↔ objects using a list of `HttpMessageConverter`s. With Jackson on the classpath, `MappingJackson2HttpMessageConverter` handles JSON automatically, so `getForObject(url, Order.class)` parses JSON into an `Order`. `StringHttpConverter`, form, and byte-array converters are also registered by default. ## Creating one correctly Don't do `new RestTemplate()` scattered everywhere. In Spring Boot inject a **`RestTemplateBuilder`** and build a bean once: ```java @Bean RestTemplate restTemplate(RestTemplateBuilder builder) { return builder .rootUri("https://api.example.com") .connectTimeout(Duration.ofSeconds(2)) .readTimeout(Duration.ofSeconds(5)) .build(); } ``` The builder applies Boot's auto-configuration (converters, timeouts, customizers). A configured `RestTemplate` is **thread-safe** and meant to be shared as a singleton. ## URI variables and encoding Methods accept URI template variables: `getForObject("/users/{id}", User.class, 42)`. RestTemplate expands and URL-encodes them for you — building URLs by string concatenation is a common bug (encoding/injection). Use the template form or a `UriComponentsBuilder`. ## Error handling By default a 4xx throws `HttpClientErrorException` and 5xx throws `HttpServerErrorException` (both subclasses of `RestClientResponseException`); connectivity problems throw `ResourceAccessException`. You can plug a custom `ResponseErrorHandler` to change this. ## Status: maintenance mode Since Spring Framework 5.0 RestTemplate is in **maintenance mode** — bugfixes/security only, no major new features. Spring 6.1 introduced **`RestClient`**, a modern fluent synchronous client built on the same infrastructure. New code should prefer `RestClient`; RestTemplate remains supported and extremely common in existing code, so you must know it. ## When to use - Existing/legacy codebase already on RestTemplate → keep using it consistently. - New synchronous code → prefer `RestClient`. - Reactive/non-blocking → `WebClient`.

  • What's the difference between getForObject and getForEntity?
    getForObject returns only the deserialized response body; getForEntity returns a ResponseEntity<T> that also exposes the HTTP status code and response headers. Use getForEntity when you need those.
  • Should you call new RestTemplate() on every request?
    No. Building it (especially with a pooled request factory) is expensive and a configured RestTemplate is thread-safe. Create one bean via RestTemplateBuilder and reuse it as a singleton.

saying these in an interview costs you the question

  • Claiming RestTemplate is asynchronous/non-blocking (it is blocking; AsyncRestTemplate was a separate, now-deprecated class)
  • Saying getForObject returns a ResponseEntity
  • Building URLs by string concatenation instead of URI template variables
  • Creating a new RestTemplate per call

context

open as a page

Is RestTemplate deprecated? How does it compare to RestClient and WebClient, and what should new code use?

level: seniorimportance: must knowfreq 65%

basics

~20 s

RestTemplate is not deprecated but is in maintenance mode (bugfixes only) since Spring 5. For new synchronous code prefer RestClient (Spring 6.1+), which has a modern fluent API on the same infrastructure. Use WebClient for reactive/non-blocking code.

open as a page

When and how do you use RestTemplate.exchange(), and how do you send custom request headers?

level: middleimportance: should knowfreq 55%

basics

~20 s

Use exchange() when the simple verb methods aren't enough — e.g. to set custom headers or read a generic type. You wrap the body and headers in an HttpEntity, pass an HttpMethod, and get back a ResponseEntity.

open as a page

How do HttpMessageConverters and ClientHttpRequestInterceptors work in RestTemplate, and what are they used for?

level: seniorimportance: should knowfreq 45%

basics

~10 s

Message converters serialize/deserialize request and response bodies (Jackson for JSON). Interceptors wrap every request/response so you can add cross-cutting behavior like auth headers, logging, or correlation IDs without touching each call site.

open as a page

How do you make RestTemplate production-ready regarding timeouts, connection pooling, and thread-safety?

level: principalimportance: should knowfreq 40%

basics

~10 s

Always set connect and read timeouts, back it with a pooled ClientHttpRequestFactory (e.g. Apache HttpClient) instead of the default one-connection-per-call factory, and reuse one configured, thread-safe RestTemplate as a singleton.

open as a page