Spring Framework Tutorial 0/14 lessons ~6 min read Lesson 12

    Spring MVC & REST APIs

    Spring MVC is the web layer most Java backends are built on.

    Course progress0%
    Focus
    8 guided sections
    Practice signal
    Examples included
    Career prep
    Foundation builder

    Introduction

    Spring MVC is the web layer most Java backends are built on. It maps HTTP requests to Java methods, converts bodies to objects (and back), validates input, handles exceptions and renders responses — JSON, HTML or anything else.

    Despite its name (MVC = Model-View-Controller, from the old server-rendered-pages era), today's Spring MVC is mostly used to build REST APIs that return JSON.

    Understanding the topic

    The request flow:

    • An HTTP request hits the DispatcherServlet.
    • A HandlerMapping chooses the controller method based on URL, HTTP verb, headers, etc.
    • Argument resolvers convert headers, path variables and JSON bodies into method parameters.
    • The controller runs and returns a value (a DTO, a ResponseEntity, a view name…).
    • A HttpMessageConverter (e.g. Jackson) serialises the response.
    • Exception handlers turn any thrown exception into an appropriate HTTP status.

    Syntax reference

    A small REST controller:

    java
    @RestController
    @RequestMapping("/api/orders")
    public class OrderController {
    private final OrderService orders;
    public OrderController(OrderService orders) {
    this.orders = orders;
    }
    @GetMapping("/{id}")
    public OrderView get(@PathVariable Long id) {
    return orders.find(id);
    }
    @GetMapping
    public Page<OrderView> list(@RequestParam(defaultValue = "0") int page,
    @RequestParam(defaultValue = "20") int size) {
    return orders.list(PageRequest.of(page, size));
    }
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public OrderView create(@Valid @RequestBody NewOrder body) {
    return orders.place(body);
    }
    }

    Informative example

    Centralised exception → HTTP mapping with @ControllerAdvice:

    java
    @RestControllerAdvice
    class ApiExceptionHandler {
    @ExceptionHandler(OrderNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    ApiError notFound(OrderNotFoundException ex) {
    return new ApiError("ORDER_NOT_FOUND", ex.getMessage());
    }
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    ApiError validation(MethodArgumentNotValidException ex) {
    var fields = ex.getFieldErrors().stream()
    .map(f -> f.getField() + ": " + f.getDefaultMessage())
    .toList();
    return new ApiError("VALIDATION_FAILED", String.join(", ", fields));
    }
    }
    record ApiError(String code, String message) {}

    Real-world use

    Almost every JSON API written in Java in the last decade uses Spring MVC under the hood. The reactive counterpart, WebFlux, exists for high-concurrency event-driven services, but MVC remains the right default for 95% of apps.

    Best practices

    • Return DTOs, not JPA entities — your API contract and your schema should evolve separately.
    • Use @ControllerAdvice for centralised exception → HTTP status mapping.
    • Validate input at the boundary with @Valid and Bean Validation annotations.
    • Version your API (/api/v1/...) before you need to.

    Common mistakes

    • Doing business logic inside the controller — keep controllers thin, push logic into services.
    • Returning sensitive fields (passwords, internal IDs) because you serialised the entity directly.
    • Forgetting CORS configuration when the frontend lives on a different origin.

    Hands-on exercise

    Build it: create a /api/books endpoint with full CRUD: list (paginated), get-by-id, create (with validation), update, delete. Add a @ControllerAdvice that returns a clean JSON error body for 404 and 400. Test each endpoint with curl or your favourite HTTP client.

    Ready to mark this lesson complete?Track your journey across the entire course.