java 30 lines · 7 steps

Header-driven endpoints in a Spring controller

A REST controller reads path variables and request headers, then handles a missing-header error locally.

Explained by highlit
1@RestController
2@RequestMapping("/api/reports")
3public class ReportController {
4 
5 private final ReportService reportService;
6 
7 public ReportController(ReportService reportService) {
8 this.reportService = reportService;
9 }
10 
11 @GetMapping("/{id}")
12 public ResponseEntity<ReportView> getReport(
13 @PathVariable Long id,
14 @RequestHeader("X-Tenant-Id") String tenantId,
15 @RequestHeader(value = "X-Report-Format", defaultValue = "summary") String format) {
16 
17 ReportView view = reportService.render(id, tenantId, format);
18 return ResponseEntity.ok()
19 .header("X-Report-Format", format)
20 .body(view);
21 }
22 
23 @ExceptionHandler(MissingRequestHeaderException.class)
24 public ResponseEntity<ApiError> handleMissingHeader(MissingRequestHeaderException ex) {
25 ApiError error = new ApiError(
26 HttpStatus.BAD_REQUEST.value(),
27 "Missing required header: " + ex.getHeaderName());
28 return ResponseEntity.badRequest().body(error);
29 }
30}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Request headers can carry cross-cutting context like tenant identity without polluting the URL path.
  2. 2Header options with defaults keep some inputs optional while others stay mandatory.
  3. 3A controller-scoped @ExceptionHandler turns framework exceptions into clean, structured error responses.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Header-driven endpoints in a Spring controller — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code