Spring Boot WebClient GET Request with Parameters

Spring Boot has revolutionized Java development, especially when it comes to building RESTful services and clients. While RestTemplate has been the go-to choice for such operations, Spring introduced WebClient with its reactive stack, offering a more powerful and flexible way to make HTTP requests. In this post, we'll create a simple REST API and then consume it using WebClient, demonstrating how to pass parameters to our API. 

Creating a Simple REST API 

Firstly, let's set up a basic Spring Boot application with a REST controller. We'll have a simple endpoint that accepts path parameters. 

Step 1: Setting Up the Spring Boot Application 

Create a Spring Boot project using Spring Initializr with the following Maven dependency:
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

Step 2: Creating the REST Controller 

Create a UserController with an endpoint that retrieves a user's details based on the user ID provided as a path variable. 

UserController.java:

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        // For demonstration, let's mock a user lookup.
        User user = new User(id, "John Doe", "johndoe@example.com");
        return ResponseEntity.ok(user);
    }

    // Nested class for User
    private static class User {
        private Long id;
        private String name;
        private String email;

        // Constructor, getters, and setters
    }
}

Consuming the API with WebClient 

With our REST API ready, let's consume it using WebClient. We’ll make a GET request to retrieve a user by their ID, passing the ID as a parameter. 

Step 1: Adding WebClient Dependency 

To use WebClient, you need to add the spring-boot-starter-webflux dependency:
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>

Step 2: Configuring WebClient 

Create a configuration class to provide a WebClient bean. 

WebClientConfig.java:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient() {
        return WebClient.builder()
                .baseUrl("http://localhost:8080/api/users")
                .build();
    }
}

Step 3: Consuming the API 

Create a service class that uses WebClient to call the API. 

UserServiceClient.java:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@Service
public class UserServiceClient {

    private final WebClient webClient;

    @Autowired
    public UserServiceClient(WebClient webClient) {
        this.webClient = webClient;
    }

    public Mono<User> getUserById(Long id) {
        return webClient.get()
                        .uri("/{id}", id)
                        .retrieve()
                        .bodyToMono(User.class);
    }

    // Nested class for User to match the API's response
     private static class User {
        private Long id;
        private String name;
        private String email;

        // Constructor, getters, and setters
     }
}
In getUserById, we're using a path variable to pass the user ID to our GET request. 

Step 4: Using the Client Service 

Now, let's make use of our UserServiceClient to make a call to the REST API. We could do this in a CommandLineRunner bean for demonstration purposes. 

DemoApplicationRunner.java:

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class DemoApplicationRunner implements CommandLineRunner {

    private final UserServiceClient userServiceClient;

    public DemoApplicationRunner(UserServiceClient userServiceClient) {
        this.userServiceClient = userServiceClient;
    }

    @Override
    public void run(String... args) {
        userServiceClient.getUserById(1L)
            .subscribe(user -> System.out.println("Retrieved User: " + user));
    }
}
The subscribe method is part of the reactive paradigm and here it's simply used to print the user details to the console. Remember, in a fully reactive environment, you'd return the Mono<User> from your web endpoint instead of subscribing to it.

Conclusion 

WebClient is a powerful part of Spring's reactive stack that allows for robust and efficient HTTP communication. By following the above steps, you can quickly set up a REST API in Spring Boot and use WebClient to consume it, making use of path variables to pass parameters. 

Comments