Request Body and ResponseEntity

@RequestBody

For POST, PUT and PATCH the client sends JSON in the request body. @RequestBody tells Spring to convert that JSON into a Java object using Jackson. Records work perfectly:

public record Product(Long id, String name, String description,
                      BigDecimal price, int stock, String category) {}

@PostMapping
public Product create(@RequestBody Product body) {
    return service.create(body);
}

Note: The request must have the header Content-Type: application/json. Without it Spring answers 415 Unsupported Media Type. Invalid JSON gives 400 Bad Request.

ResponseEntity: Status, Headers and Body

Returning a plain object always gives 200 OK. To choose the status code and add headers, return ResponseEntity<T>:

@PostMapping
public ResponseEntity<Product> create(@RequestBody Product body) {
    Product saved = service.create(body);
    URI location = ServletUriComponentsBuilder.fromCurrentRequest()
            .path("/{id}").buildAndExpand(saved.id()).toUri();
    return ResponseEntity.created(location).body(saved);        // 201 + Location header
}

@GetMapping("/{id}")
public ResponseEntity<Product> get(@PathVariable Long id) {
    return service.find(id)
            .map(ResponseEntity::ok)                                // 200 + body
            .orElse(ResponseEntity.notFound().build());            // 404, empty body
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
    service.delete(id);
    return ResponseEntity.noContent().build();                     // 204
}
BuilderStatus
ResponseEntity.ok(body)200 OK
ResponseEntity.created(uri).body(b)201 Created + Location
ResponseEntity.accepted().build()202 Accepted
ResponseEntity.noContent().build()204 No Content
ResponseEntity.badRequest().body(b)400 Bad Request
ResponseEntity.notFound().build()404 Not Found
ResponseEntity.status(HttpStatus.CONFLICT).body(b)any status

@ResponseStatus as a Shortcut

If a method always returns the same status, annotate it instead of building a ResponseEntity:

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Product create(@RequestBody Product body) {
    return service.create(body);
}

Tip: Use @ResponseStatus for simple cases and ResponseEntity when the status or headers depend on the result (found / not found, Location header, caching headers).