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
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.