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.