REST Client in Springboot

There are several ways to communicate to an external service over HTTP/HTTPS in Springboot. They are RestTemplate, RestClient and WebClient. WebClient is used when there is Spring Web Flux present in the project. Generally, we used to use RestTemplate. However, RestClient is the modern approach and is used since Spring Framework 6.1 and Springboot 3.2.

In this article, we will see some simple examples on how to use RestClient in Springboot.

I am using the public APIs provided in JSONPlaceholder for demonstration. These are just dummy APIs and doesn’t actually do anything.

Build the client

Before we can make a request to the server, we need to build a RestClient object. Springboot automatically provides a Builder object for easily building the RestClient object.

private final String JSON_PLACEHOLDER_BASE_URL = "http://jsonplaceholder.typicode.com";

@Autowired
private RestClient.Builder restClientBuilder;

private RestClient getClient(){
        return restClientBuilder
                .baseUrl(JSON_PLACEHOLDER_BASE_URL)
                .build();
}

Sometimes, we might need to add some default headers. We can add a Authorization header in the following way.

private final String JSON_PLACEHOLDER_BASE_URL = "http://jsonplaceholder.typicode.com";

@Autowired
private RestClient.Builder restClientBuilder;

private RestClient getClient(String token){
        return restClientBuilder
                .baseUrl(JSON_PLACEHOLDER_BASE_URL)
                .defaultHeader(HttpHeaders.AUTHORIZATION,token)
                .build();
}

POST

In order to do a POST request and send a payload to the server use the following code. The response represents the saved object. Notice, we are providing PostDTO.class in body() method to tell the serializer which class to use during serializing the response body. If we want to access the ResponseEntity instead of the body, we can use the toEntity() method.

public PostDTO sendPost(PostDTO post) {
        RestClient client = getClient();

        return client.post()
                .uri("/posts")
                .body(post)
                .retrieve()
                .body(PostDTO.class);
}
public ResponseEntity<PostDTO> sendPost(PostDTO post) {
        RestClient client = getClient();

        return client.post()
                .uri("/posts")
                .body(post)
                .retrieve()
                .toEntity(PostDTO.class);
    }

GET

Now, let’s fetch some data from the server. Note that, in case of nested JSON structure in response body or the response body contains an array of objects, we need to use ParameterizedTypeReference<T> class to properly serialize the response body. Here, T represents the data type of the response body which is usually a DTO.

public PostDTO[] getPosts(){
        RestClient client = getClient();

        return client.get()
                .uri("/posts")
                .retrieve()
                .body(new ParameterizedTypeReference<PostDTO[]>() {});
}
public CourseDTO<StudentDTO[]> getCourse(int id){
        RestClient client = getClient();

        return client.get()
                .uri("/course/"+id)
                .retrieve()
                .body(new ParameterizedTypeReference<CourseDTO<StudentDTO[]>>() {});
    }

where CourseDTO.class may look like this.

public class CourseDTO{
    int courseId;
    String courseTitle;
    long totalStudents;
    StudentDTO[] students;
}

PUT

If we want to update a resource, we can do so with a PUT request.

public PostDTO updatePost(int id,PostDTO post) {
        RestClient client = getClient();

        return client.put()
                .uri("/posts/"+id)
                .body(post)
                .retrieve()
                .body(PostDTO.class);
}

DELETE

In order to delete a resource, we use the following code. This time the response body is empty. So, we map to a bodiless entity and return a boolean result according to the HTTP status returned from the server.

public boolean deletePost(int id) {
        RestClient client = getClient();

        ResponseEntity<Void> response = client.delete()
                .uri("/posts/"+id)
                .retrieve()
                .toBodilessEntity();

        return response.getStatusCode() == HttpStatus.OK;
}

In this article, I just went over how we can very easily call an HTTP service using RestClient in Springboot. This article should be a good starting point and the official documentation can help in learning further details and complexity. In next few articles, I will try to cover how to add request parameters in POST request, upload a file using Form-Data and how to handle errors in RestClient. Please post your query in the comment section if you need further clarification.

Leave a Reply