Cheat SheetsSpring BootREST & Web

REST & Web — Cheat Sheet

Spring Boot · 3 topics. Download the PDF or the Instagram carousel and share it.

Cheat Sheet · AiCanCode.org
REST & Web
Spring Boot3 topicsQuick revision reference
1

REST Controllers

@RestController combines @Controller and @ResponseBody — every method returns data serialized directly to the response body, not a view name. This is the building block of every Spring Boot REST API.

  • @RestController = @Controller + @ResponseBody — return values go directly to the HTTP response.
  • Use class-level @RequestMapping for the base path and method-level annotations for HTTP verbs.
  • @PathVariable extracts URL segments; @RequestParam extracts query string values.
  • Return ResponseEntity when you need to control status code and response headers.
  • @ResponseStatus on the method sets the default status code (use 201 for POST creates, 204 for deletes).
  • Jackson automatically serializes return values to JSON using field names or @JsonProperty.
Java — full CRUD controller
@RestController
@RequestMapping("/api/v1/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    // GET /api/v1/users
    @GetMapping
    public List<UserDto> getAllUsers() {
        return userService.findAll();
    }

    // GET /api/v1/users/{id}
    @GetMapping("/{id}")
    public ResponseEntity<UserDto> getUser(@PathVariable Long id) {
        return userService.findById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }

    // POST /api/v1/users  → 201 Created
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public UserDto createUser(@RequestBody @Valid CreateUserRequest req) {
        return userService.create(req);
    }

    // PUT /api/v1/users/{id}
    @PutMapping("/{id}")
    public UserDto updateUser(@PathVariable Long id,
                              @RequestBody @Valid UpdateUserRequest req) {
        return userService.update(id, req);
    }

    // DELETE /api/v1/users/{id}  → 204 No Content
    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void deleteUser(@PathVariable Long id) {
        userService.delete(id);
    }
}
2

Request & Response

@RequestBody deserializes the HTTP request body into a Java object; ResponseEntity gives you full control over status, headers, and body. These two are the backbone of every REST interaction.

  • @RequestBody uses HttpMessageConverter (Jackson) to deserialize the request body into a Java object.
  • Always pair @RequestBody with @Valid to trigger Bean Validation before the method executes.
  • ResponseEntity<T> lets you set status code, headers, and body — use it for conditional or non-200 responses.
  • Return Location header on 201 Created responses — use ServletUriComponentsBuilder to build it from the current request.
  • Spring Boot 3+ supports ProblemDetail (RFC 7807) natively — consistent error response format across all endpoints.
  • Use @ResponseStatus on the method for fixed status codes; use ResponseEntity when the status is dynamic.
Java — @RequestBody with @Valid on a record DTO
// DTO as a Java record (Java 16+) — immutable, no boilerplate
public record CreateOrderRequest(
    @NotBlank String customerId,
    @NotEmpty List<@Valid OrderItemDto> items,
    @NotBlank String deliveryAddress
) {}

public record OrderItemDto(
    @NotBlank String productId,
    @Min(1) int quantity
) {}

@RestController
@RequestMapping("/api/v1/orders")
public class OrderController {

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public OrderDto createOrder(@RequestBody @Valid CreateOrderRequest request) {
        // Jackson has already deserialized JSON → CreateOrderRequest
        // @Valid has already checked constraints
        // If validation fails → MethodArgumentNotValidException → 400
        return orderService.create(request);
    }
}

// Example JSON request body:
// {
//   "customerId": "usr_123",
//   "items": [{ "productId": "prod_456", "quantity": 2 }],
//   "deliveryAddress": "123 Main St"
// }
3

Bean Validation

Jakarta Bean Validation (@Valid, @NotBlank, @Size, @Email) validates request bodies before they reach your service. Custom validators handle business rules that built-in constraints can't express.

  • Add spring-boot-starter-validation — Bean Validation is not included in spring-boot-starter-web.
  • @Valid on @RequestBody triggers constraint checking; violations throw MethodArgumentNotValidException → 400.
  • Use @Valid on nested fields to recursively validate inner DTOs.
  • Implement ConstraintValidator for business-rule validation (unique email, valid coupon code, etc.).
  • Handle MethodArgumentNotValidException in @ControllerAdvice to return consistent, field-level error JSON.
  • @Validated at class level on @Service enables constraint validation on service method parameters too.
Java — built-in constraints on a record DTO
<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

// Request DTO with constraints
public record CreateUserRequest(
    @NotBlank(message = "Email is required")
    @Email(message = "Invalid email format")
    String email,

    @NotBlank
    @Size(min = 8, max = 100, message = "Password must be 8-100 characters")
    String password,

    @NotBlank
    @Size(min = 2, max = 100)
    String fullName,

    @Min(value = 13, message = "Must be at least 13")
    @Max(value = 120)
    Integer age,

    @Pattern(regexp = "^[6-9]\d{9}$", message = "Invalid Indian mobile number")
    String mobile,

    @Valid  // triggers nested validation
    @NotNull
    AddressDto address
) {}

public record AddressDto(
    @NotBlank String street,
    @NotBlank String city,
    @NotBlank @Size(min = 6, max = 6) String pincode
) {}

@RestController
@RequestMapping("/api/v1/users")
public class UserController {

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public UserDto createUser(@RequestBody @Valid CreateUserRequest req) {
        // Only reached if ALL constraints pass
        return userService.create(req);
    }
}
Learn this free with Aria, your AI tutor → AiCanCode.org/learn/spring-boot