Guide for creating RESTful controllers with proper request/response handling, validation, and documentation. Use this when implementing new API endpoints or refactoring existing controllers.
Guide for creating RESTful controllers with proper request/response handling, validation, and documentation. Use this when implementing new API endpoints or refactoring existing controllers.
Spring Boot REST Controller Best Practices
Follow these practices for implementing RESTful APIs.
@RestController@RequestMapping("/api/appointments")publicclassAppointmentController {
// GET all - Returns 200 OK@GetMappingpublic List<AppointmentResponseDTO> getAll() {
return appointmentService.findAll();
}
// GET by ID - Returns 200 OK or 404 Not Found@GetMapping("/{id}")public AppointmentResponseDTO getById(@PathVariable Long id) {
return appointmentService.findById(id);
}
// POST create - Returns 201 Created@PostMappingpublic ResponseEntity<AppointmentResponseDTO> create(
@Valid@RequestBody AppointmentRequestDTO request) {
AppointmentResponseDTOcreated= appointmentService.create(request);
URIlocation= ServletUriComponentsBuilder
.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(created.getId())
.toUri();
return ResponseEntity.created(location).body(created);
}
// PUT update - Returns 200 OK or 404 Not Found@PutMapping("/{id}")public AppointmentResponseDTO update(
@PathVariable Long id,
@Valid@RequestBody AppointmentRequestDTO request) {
return appointmentService.update(id, request);
}
// PATCH partial update - Returns 200 OK or 404 Not Found@PatchMapping("/{id}/status")public AppointmentResponseDTO updateStatus(
@PathVariable Long id,
@RequestParam String status) {
return appointmentService.updateStatus(id, status);
}
// DELETE - Returns 204 No Content@DeleteMapping("/{id}")public ResponseEntity<Void> delete(@PathVariable Long id) {
appointmentService.delete(id);
return ResponseEntity.noContent().build();
}
}
Request Validation
// Request DTO with validationpublicclassAppointmentRequestDTO {
@NotNull(message = "Customer ID is required")private Long customerId;
@NotNull(message = "Employee ID is required")private Long employeeId;
@NotNull(message = "Service type ID is required")private Long serviceTypeId;
@NotNull(message = "Appointment time is required")@FutureOrPresent(message = "Appointment time must be in the future")private LocalDateTime appointmentTime;
@Size(max = 500, message = "Notes cannot exceed 500 characters")private String notes;
// Getters and setters
}
// Controller with validation@PostMappingpublic ResponseEntity<AppointmentResponseDTO> create(
@Valid@RequestBody AppointmentRequestDTO request) {
// Request is automatically validatedreturn ResponseEntity.status(HttpStatus.CREATED)
.body(appointmentService.create(request));
}