skip to content

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