REST API Fundamentals
Controllers, validation, exception handling โ the annotations, the patterns, and the two things most people get wrong.
Controller Basics
@RestController = @Controller + @ResponseBody.
Every method return value is serialised to JSON (via Jackson) and written directly to the HTTP response body.
@RequestMapping at class level sets the base path. Constructor injection in controllers โ
@Autowired on the field is wrong here too.
One-sentence mental model: the front controller that routes all HTTP requests to the correct
@RestController method based on URL, HTTP method, and content type.
Request Mapping
| Annotation | HTTP Verb | Typical Use |
|---|---|---|
@GetMapping | GET | Read / list |
@PostMapping | POST | Create |
@PutMapping | PUT | Full replace |
@PatchMapping | PATCH | Partial update |
@DeleteMapping | DELETE | Delete |
@PathVariableโ identity:/users/{id}@RequestParamโ filter/option:/users?status=active- Rule of thumb: identity โ path, filter/option โ query param
Request Data
@RequestBodyโ JSON โ Java object via Jackson. RequiresContent-Type: application/json.@RequestHeaderโ reading a specific header value
Responses
Return type choices: plain object (Spring picks 200 OK) vs ResponseEntity<T>
when you need to control status code, headers, or conditional body.
| Scenario | Status |
|---|---|
| Successful GET / PUT | 200 OK |
| Successful POST (created) | 201 Created |
| Successful DELETE | 204 No Content |
| Validation failure | 400 Bad Request |
| Not authenticated | 401 Unauthorized |
| Authenticated, no permission | 403 Forbidden |
| Resource not found | 404 Not Found |
Validation
@Valid on @RequestBody triggers Bean Validation.
Put constraint annotations on the DTO fields, not the entity.
@NotNull/@NotBlankโ null vs empty string distinction@Size(min, max)โ string length or collection size@Min/@Maxโ numeric bounds@Email/@Patternโ format validation
@Validated supports group validation and works on the service layer too.
@Valid is the standard JSR-303 annotation โ works on @RequestBody params.
Without a handler, validation failures return a noisy 400 โ you want to intercept this.
Exception Handling
Global exception handler โ applies to all controllers. @ExceptionHandler(SomeException.class)
maps an exception type to a structured error response. Specific handlers win over general ones.
The pattern: timestamp, status, error, message, path.
Spring Boot 3.x supports Problem Details (RFC 7807) natively via ProblemDetail.
@ControllerAdvice class is outside the component scan package,
it is silently ignored. No error, no warning โ just no exception handling.