DEV Community

Dev Cookies
Dev Cookies

Posted on

πŸ”₯ Simplified REST API Calls in Spring Boot 3 with RestClient – Full CRUD Example

With Spring Boot 3 and Spring Framework 6, making HTTP calls just got cleaner and more intuitive. Say goodbye to verbose RestTemplate or clunky WebClient for simple use cases β€” meet RestClient: the new fluent API for synchronous REST calls.

In this post, you'll learn how to perform full CRUD operations (Create, Read, Update, Delete) on an Employee resource using Spring’s RestClient, along with custom headers and best practices.


βœ… Why RestClient?

  • 🌱 Introduced in Spring Framework 6
  • 🧼 Cleaner syntax than RestTemplate
  • ⚑️ Fluent, builder-based API
  • πŸ›‘ Ideal for simple REST use-cases in synchronous systems

πŸ“¦ 1. Define the Employee DTO

public class Employee {
    private Long id;
    private String name;
    private String department;

    // Constructors
    public Employee() {}
    public Employee(Long id, String name, String department) {
        this.id = id;
        this.name = name;
        this.department = department;
    }

    // Getters and Setters
    // ...
}
Enter fullscreen mode Exit fullscreen mode

πŸ› οΈ 2. Create a RestClient Instance

RestClient restClient = RestClient.create();
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ 3. POST β€” Create a New Employee

Employee newEmployee = new Employee(null, "Nitesh", "Engineering");

Employee createdEmployee = restClient
    .post()
    .uri("http://localhost:8080/api/employees")
    .contentType(MediaType.APPLICATION_JSON)
    .headers(headers -> {
        headers.setBearerAuth("your-token-here");
        headers.set("X-Client", "RestClient-Demo");
    })
    .body(newEmployee)
    .retrieve()
    .body(Employee.class);

System.out.println("Created Employee: " + createdEmployee.getId());
Enter fullscreen mode Exit fullscreen mode

πŸ“₯ 4. GET β€” Fetch Employee by ID

Long id = 101L;

Employee fetchedEmployee = restClient
    .get()
    .uri("http://localhost:8080/api/employees/{id}", id)
    .headers(headers -> headers.set("Authorization", "Bearer your-token-here"))
    .retrieve()
    .body(Employee.class);

System.out.println("Fetched: " + fetchedEmployee.getName());
Enter fullscreen mode Exit fullscreen mode

✏️ 5. PUT β€” Update Employee

Employee updateRequest = new Employee(101L, "Nitesh Kumar", "Platform");

Employee updatedEmployee = restClient
    .put()
    .uri("http://localhost:8080/api/employees/{id}", updateRequest.getId())
    .contentType(MediaType.APPLICATION_JSON)
    .headers(headers -> headers.set("Authorization", "Bearer your-token-here"))
    .body(updateRequest)
    .retrieve()
    .body(Employee.class);

System.out.println("Updated to: " + updatedEmployee.getDepartment());
Enter fullscreen mode Exit fullscreen mode

❌ 6. DELETE β€” Remove Employee

Long deleteId = 101L;

restClient
    .delete()
    .uri("http://localhost:8080/api/employees/{id}", deleteId)
    .headers(headers -> headers.set("Authorization", "Bearer your-token-here"))
    .retrieve()
    .toBodilessEntity();

System.out.println("Employee with ID " + deleteId + " deleted.");
Enter fullscreen mode Exit fullscreen mode

βš™οΈ 7. Sample Backend Controller (Optional)

If you're testing locally, here's the Spring Boot controller:

@RestController
@RequestMapping("/api/employees")
public class EmployeeController {

    @PostMapping
    public ResponseEntity<Employee> create(@RequestBody Employee employee) {
        employee.setId(101L); // Simulate ID generation
        return ResponseEntity.ok(employee);
    }

    @GetMapping("/{id}")
    public ResponseEntity<Employee> getById(@PathVariable Long id) {
        return ResponseEntity.ok(new Employee(id, "Nitesh", "Engineering"));
    }

    @PutMapping("/{id}")
    public ResponseEntity<Employee> update(@PathVariable Long id, @RequestBody Employee employee) {
        employee.setId(id);
        return ResponseEntity.ok(employee);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@PathVariable Long id) {
        return ResponseEntity.noContent().build();
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸš€ Final Thoughts

Spring’s new RestClient is a refreshingly clean and modern alternative to RestTemplate. It’s especially handy for straightforward client use-cases where you want a readable, chainable API without going reactive.

πŸ”” Pro Tips:

  • Use .headers() to inject Authorization and custom headers.
  • Use RestClient.Builder for reusable configuration (e.g., base URL, default headers).
  • For more advanced use-cases (like retry, circuit breaker), consider using WebClient or integrating with Resilience4j.

πŸ”— Resources

Top comments (0)