Spring Boot WebClient PUT Request Example

In this tutorial, we will build an 'Update Employee' REST API and demonstrate how to consume it using WebClient, including passing a request body. 

Spring Boot WebClient PUT Request Example

First, you'll set up a Spring Boot application with a MySQL database to store employee data. Then, you'll create a service to handle data persistence and finally use WebClient to update an employee's data. Let's get started.

Step 1: Set Up the Spring Boot Project with MySQL 

Add the necessary dependencies to your pom.xml:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>

Step 2: Configure MySQL Database 

Set up your application.properties or application.yml with your MySQL configuration: 

application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/your_database spring.datasource.username=your_username spring.datasource.password=your_password spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true

Replace your_database, your_username, and your_password with your actual MySQL database name and credentials.

Step 3: Create the Employee Entity and Repository 

Define an Employee entity and a corresponding repository. 

Employee.java:

import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; @Entity @Getter @Setter @Table(name = "employees") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String department; // Constructors, getters, and setters can be omitted for brevity (use Lombok) }

EmployeeRepository.java:

import org.springframework.data.jpa.repository.JpaRepository; public interface EmployeeRepository extends JpaRepository<Employee, Long> { // Custom methods if needed }

Step 4: Implement the Service Layer 

Create a service to handle CRUD operations. 

EmployeeService.java:

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class EmployeeService { private final EmployeeRepository employeeRepository; @Autowired public EmployeeService(EmployeeRepository employeeRepository) { this.employeeRepository = employeeRepository; } public Employee updateEmployee(Long id, Employee employeeDetails) { Employee employee = employeeRepository.findById(id) .orElseThrow(() -> new RuntimeException("Employee not found")); employee.setName(employeeDetails.getName()); employee.setDepartment(employeeDetails.getDepartment()); return employeeRepository.save(employee); } // Additional service methods }

Step 5: Create the REST Controller 

Define a controller with a PUT mapping to update an employee. 

EmployeeController.java:

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/employees") public class EmployeeController { private final EmployeeService employeeService; @Autowired public EmployeeController(EmployeeService employeeService) { this.employeeService = employeeService; } @PutMapping("/{id}") public ResponseEntity<Employee> updateEmployee(@PathVariable Long id, @RequestBody Employee employee) { Employee updatedEmployee = employeeService.updateEmployee(id, employee); return ResponseEntity.ok(updatedEmployee); } }

Step 6: Configure WebClient

Set up WebClient in your configuration:
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/employees") .build(); } }

Step 7: Use WebClient to Consume the Update API 

With your REST API in place, let's consume it using WebClient. 

WebClientService.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 WebClientService { private final WebClient webClient; @Autowired public WebClientService(WebClient.Builder webClientBuilder) { this.webClient = webClientBuilder.baseUrl("http://localhost:8080").build(); } public Mono<Employee> updateEmployee(Long id, Employee employee) { return webClient.put() .uri("/api/employees/{id}", id) .bodyValue(employee) .retrieve() .bodyToMono(Employee.class); } // Handling errors and other methods can be added as well }

In this service, the updateEmployee method sends a PUT request to our API endpoint. The bodyValue(employee) sets the request body, and uri method includes path variable substitution. 

Step 8: Calling WebClient Service from the Application 

Finally, you might use the WebClientService from anywhere in your application. A typical example could be a scheduled job or during application startup: 

ApplicationRunner.java:

import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class ApplicationRunner implements CommandLineRunner { private final WebClientService webClientService; public ApplicationRunner(WebClientService webClientService) { this.webClientService = webClientService; } @Override public void run(String... args) throws Exception { Employee employeeToUpdate = new Employee(); employeeToUpdate.setName("John Doe Updated"); employeeToUpdate.setDepartment("Engineering Updated"); webClientService.updateEmployee(1L, employeeToUpdate) .subscribe( employee -> System.out.println("Updated Employee: " + employee.getName()), error -> System.err.println("Failed to update employee: " + error.getMessage()) ); } }
This ApplicationRunner will execute at the startup of the Spring Boot application, calling the updateEmployee method of WebClientService, and logging the result to the console.

Conclusion

In this blog post, we've created a complete Spring Boot application with a RESTful endpoint for updating employee records in a MySQL database. Furthermore, we've illustrated how to consume this endpoint with Spring Boot's WebClient, performing a PUT request with an employee object as the request body. The reactive nature of WebClient ensures that we're ready for scalable and non-blocking operations, essential for today's high-performance applications.

Comments