# How to make HTTP requests using RestTemplate in Spring Boot 

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Jul 25, 2019, updated Sep 24, 2022. Topics: Spring Boot, Spring Web.
Canonical URL: https://attacomsian.com/blog/http-requests-resttemplate-spring-boot

> A complete guide to learning how to make HTTP GET and POST requests using the RestTemplate class in a Spring Boot application.

The RestTemplate class in Spring Framework is a synchronous HTTP client for making HTTP requests to consume RESTful web services. It exposes a simple and easy-to-use template method API for sending an HTTP request and handling the HTTP response. 

The RestTemplate class also provides aliases for all supported HTTP request methods, such as GET, POST, PUT, DELETE, and OPTIONS.

In this tutorial, we will learn how to use the Spring REST client &mdash; **RestTemplate** &mdash; for sending HTTP requests in a Spring Boot application.

## Dependencies

Since the RestTemplate class is a part of the Spring Web project, we only need the `spring-boot-starter-web` dependency. Add the following dependency to your Gradle project's `build.gradle` file:

```groovy
implementation 'org.springframework.boot:spring-boot-starter-web'
```

If you are using Maven, add the following dependency to your `pom.xml` file:

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
```

## GET Request

Let's start with a simple example to retrieve a list of posts using RestTemplate's `getForObject()` method:

<p class="file-desc"><span>RestService.java</span></p>

```java
@Service
public class RestService {

    private final RestTemplate restTemplate;

    public RestService(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }

    public String getPostsPlainJSON() {
        String url = "https://jsonplaceholder.typicode.com/posts";
        return this.restTemplate.getForObject(url, String.class);
    }
}
```

Notice the response returned by the `getForObject()` method. It is a plain [JSON](https://attacomsian.com/blog/what-is-json) string. We can easily [parse this JSON string into an object](https://attacomsian.com/blog/processing-json-spring-boot) using Jackson. 

### Get Response as Object

We can also map the response directly to a model class. Let us first create a model class:

<p class="file-desc"><span>Post.java</span></p>

```java
public class Post implements Serializable {

    private int userId;
    private int id;
    private String title;
    private String body;

    // getters and setters
}
```

Now we can simply use the `Post` class as response type in `getForObject()` method:

```javascript
public Post[] getPostsAsObject() {
    String url = "https://jsonplaceholder.typicode.com/posts";
    return this.restTemplate.getForObject(url, Post[].class);
}
```

### URL Parameters

If you want to pass the query parameters, just append them to the URL:

```java
String url = "https://jsonplaceholder.typicode.com/posts?userId=2";
```

Another way is to use placeholders in the URL for parameters:

```java
public Post getPostWithUrlParameters() {
    String url = "https://jsonplaceholder.typicode.com/posts/{id}";
    return this.restTemplate.getForObject(url, Post.class, 1);
}
```

### Response Handing

If you want to manipulate the response (like checking HTTP status code), use the `getForEntity()` method like below:

```java
public Post getPostWithResponseHandling() {
    String url = "https://jsonplaceholder.typicode.com/posts/{id}";
    ResponseEntity<Post> response = this.restTemplate.getForEntity(url, Post.class, 1);
    if(response.getStatusCode() == HttpStatus.OK) {
        return response.getBody();
    } else {
        return null;
    }
}
```

### Custom Request Headers

If you want to set the request headers like `content-type`, `accept`, or any custom header, use the generic `exchange()` method:

```java
public Post getPostWithCustomHeaders() {
    String url = "https://jsonplaceholder.typicode.com/posts/{id}";

    // create headers
    HttpHeaders headers = new HttpHeaders();
    // set `accept` header
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
    // set custom header
    headers.set("x-request-source", "desktop");

    // build the request
    HttpEntity request = new HttpEntity(headers);

    // use `exchange` method for HTTP call
    ResponseEntity<Post> response = this.restTemplate.exchange(url, HttpMethod.GET, request, Post.class, 1);
    if(response.getStatusCode() == HttpStatus.OK) {
        return response.getBody();
    } else {
        return null;
    }
}
```

> **Quick Guide:** Check out [RestTemplate GET Request with Parameters and Headers](https://attacomsian.com/blog/spring-boot-resttemplate-get-request-parameters-headers) for more GET request examples.

## POST Request

A POST request is used to create a new resource. The RestTemplate class offers several template methods like `postForObject()`, `postForEntity()`, and `postForLocation()` for making POST request. 

The first two methods are similar to what we discussed above for the response format. The last method returns the location of the newly created resource instead of the complete resource.

Let us make use of the `postForEntity()` method to create a new post:

```javascript
public Post createPost() {
    String url = "https://jsonplaceholder.typicode.com/posts";

    // create headers
    HttpHeaders headers = new HttpHeaders();
    // set `content-type` header
    headers.setContentType(MediaType.APPLICATION_JSON);
    // set `accept` header
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

    // create a map for post parameters
    Map<String, Object> map = new HashMap<>();
    map.put("userId", 1);
    map.put("title", "Introduction to Spring Boot");
    map.put("body", "Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications.");

    // build the request
    HttpEntity<Map<String, Object>> entity = new HttpEntity<>(map, headers);

    // send POST request
    ResponseEntity<Post> response = this.restTemplate.postForEntity(url, entity, Post.class);

    // check response status code
    if (response.getStatusCode() == HttpStatus.CREATED) {
        return response.getBody();
    } else {
        return null;
    }
}
```

Alternatively, we can also use the `postForObject()` method to create a new post:

```java
public Post createPostWithObject() {
    String url = "https://jsonplaceholder.typicode.com/posts";

    // create headers
    HttpHeaders headers = new HttpHeaders();
    // set `content-type` header
    headers.setContentType(MediaType.APPLICATION_JSON);
    // set `accept` header
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

    // create a post object
    Post post = new Post(1, "Introduction to Spring Boot",
            "Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications.");

    // build the request
    HttpEntity<Post> entity = new HttpEntity<>(post, headers);

    // send POST request
    return restTemplate.postForObject(url, entity, Post.class);
}
```

> **Quick Guide:** Check out [RestTemplate POST Request with JSON and Headers](https://attacomsian.com/blog/spring-boot-resttemplate-post-request-json-headers) for more POST request examples.

## PUT Request

The RestTemplate class provides the `put()` method that can be used to update a resource:

```java
public void updatePost() {
    String url = "https://jsonplaceholder.typicode.com/posts/{id}";

    // create headers
    HttpHeaders headers = new HttpHeaders();
    // set `content-type` header
    headers.setContentType(MediaType.APPLICATION_JSON);
    // set `accept` header
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

    // create a post object
    Post post = new Post(4, "New Title", "New Body");

    // build the request
    HttpEntity<Post> entity = new HttpEntity<>(post, headers);

    // send PUT request to update post with `id` 10
    this.restTemplate.put(url, entity, 10);
}
```

The `put()` method does not return anything. If you want to process the response, use the generic `exchange()` method instead: 

```java
public Post updatePostWithResponse() {
    String url = "https://jsonplaceholder.typicode.com/posts/{id}";

    // create headers
    HttpHeaders headers = new HttpHeaders();
    // set `content-type` header
    headers.setContentType(MediaType.APPLICATION_JSON);
    // set `accept` header
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

    // create a post object
    Post post = new Post(4, "New Title", "New Body");

    // build the request
    HttpEntity<Post> entity = new HttpEntity<>(post, headers);

    // send PUT request to update post with `id` 10
    ResponseEntity<Post> response = this.restTemplate.exchange(url, HttpMethod.PUT, entity, Post.class, 10);

    // check response status code
    if (response.getStatusCode() == HttpStatus.OK) {
        return response.getBody();
    } else {
        return null;
    }
}
```

## DELETE Request

To delete an existing resource, you can use the `delete()` method:

```java
public void deletePost() {
    String url = "https://jsonplaceholder.typicode.com/posts/{id}";

    // send DELETE request to delete post with `id` 10
    this.restTemplate.delete(url, 10);
}
```

## HEAD Request

The RestTemplate class offers `headForHeaders()` method to retrieve headers:

```java
public HttpHeaders retrieveHeaders() {
    String url = "https://jsonplaceholder.typicode.com/posts";

    // send HEAD request
    return this.restTemplate.headForHeaders(url);
}
```

## OPTIONS Request

Let us use the `optionsForAllow()` method to get a list of all supported HTTP operations:

```java
public Set<HttpMethod> allowedOperations() {
    String url = "https://jsonplaceholder.typicode.com/posts";

    // send HEAD request
    return this.restTemplate.optionsForAllow(url);
}
```

## Error Handling

If there is an error during the request execution or the server returns a non-successful HTTP error (4xx or 5xx), RestTemplate will throw an exception. You can catch the `HttpStatusCodeException` in the `catch` block to get the response body and headers:

```java
public String unknownRequest() {
    try {
        String url = "https://jsonplaceholder.typicode.com/404";
        return this.restTemplate.getForObject(url, String.class);
    } catch (HttpStatusCodeException ex) {
        // raw http status code e.g `404`
        System.out.println(ex.getRawStatusCode());
        // http status code e.g. `404 NOT_FOUND`
        System.out.println(ex.getStatusCode().toString());
        // get response body
        System.out.println(ex.getResponseBodyAsString());
        // get http headers
        HttpHeaders headers= ex.getResponseHeaders();
        System.out.println(headers.get("Content-Type"));
        System.out.println(headers.get("Server"));
    }

    return null;
}
```

> **Quick Guide:** Learn more about [handling errors while using the RestTemplate](https://attacomsian.com/blog/spring-boot-resttemplate-error-handling) in a Spring Boot application.

## RestTemplate Connection Timeout

There are two types of timeouts: connection timeout and read timeout. By default, RestTemplate has infinite timeouts. 
But we can change this behavior by using the `RestTemplateBuilder` class for setting the connection and read timeouts:

```java
public RestService(RestTemplateBuilder restTemplateBuilder) {
    // set connection and read timeouts
    this.restTemplate = restTemplateBuilder
            .setConnectTimeout(Duration.ofSeconds(500))
            .setReadTimeout(Duration.ofSeconds(500))
            .build();
}
```

> **Source code:** Download the complete source code from [GitHub](https://github.com/attacomsian/code-examples/tree/master/spring-boot/rest-template) available under MIT license.

## Conclusion

That's all for using Spring Framework's RestTemplate class to call remote RESTful web services in a Spring Boot application. We talked about almost all HTTP verbs and used RestTemplate to make requests for all of them.

If you are interested in learning more, check out the [processing JSON data in Spring Boot](https://attacomsian.com/blog/processing-json-spring-boot) guide. It will introduce you to Jackson, which is used with RestTemplate for parsing unknown JSON data.

**Read Next:** [RestTemplate Basic Authentication Example](https://attacomsian.com/blog/resttemplate-basic-authentication)
