Guide for creating RESTful controllers with proper request/response handling, validation, and documentation. Use this when implementing new API endpoints or refactoring existing controllers.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
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));
}