Home/Learn/Spring Boot/REST Controllers

REST Controllers

Beginner
REST & Web

@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.

Overview

@RestController marks a class as an HTTP request handler where return values are written directly to the HTTP response body as JSON (via Jackson by default). Request mapping annotations (@GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping) bind HTTP methods and URL patterns to handler methods. Spring MVC's DispatcherServlet routes incoming requests through a chain of HandlerMapping → HandlerAdapter → the controller method → MessageConverter to produce the response.

Basic CRUD Controller

A typical REST controller exposes CRUD operations as HTTP methods. Use @RequestMapping at class level for the base path, and method-level annotations for specific operations. Return types can be plain objects (auto-serialized to JSON), ResponseEntity (when you need control over status/headers), or void (for 204 No Content).

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);
    }
}

Path Variables, Query Params & Request Headers

Spring MVC extracts URL segments with @PathVariable, query string values with @RequestParam, and HTTP headers with @RequestHeader. @RequestParam can have defaults and be marked as optional.

Java — @PathVariable, @RequestParam, @RequestHeader
@RestController
@RequestMapping("/api/v1/products")
public class ProductController {

    // GET /api/v1/products/electronics/42
    @GetMapping("/{category}/{id}")
    public ProductDto getProduct(
            @PathVariable String category,
            @PathVariable Long id) {
        return productService.find(category, id);
    }

    // GET /api/v1/products?page=0&size=20&sort=name&search=laptop
    @GetMapping
    public Page<ProductDto> listProducts(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(required = false) String sort,
            @RequestParam(required = false) String search) {
        return productService.list(page, size, sort, search);
    }

    // Reading a custom request header
    @GetMapping("/featured")
    public List<ProductDto> featured(
            @RequestHeader("X-Region") String region,
            @RequestHeader(value = "X-Currency", defaultValue = "INR") String currency) {
        return productService.getFeatured(region, currency);
    }
}

Key Points to Remember

  • 1@RestController = @Controller + @ResponseBody — return values go directly to the HTTP response.
  • 2Use class-level @RequestMapping for the base path and method-level annotations for HTTP verbs.
  • 3@PathVariable extracts URL segments; @RequestParam extracts query string values.
  • 4Return ResponseEntity when you need to control status code and response headers.
  • 5@ResponseStatus on the method sets the default status code (use 201 for POST creates, 204 for deletes).
  • 6Jackson automatically serializes return values to JSON using field names or @JsonProperty.

Interview Questions

Sign in to ask Aria
1

What is the difference between @Controller and @RestController?

EasyInfosys
2

When would you return ResponseEntity instead of the plain object?

EasyTCS
3

What is the difference between @RequestParam and @PathVariable?

EasyWipro
4

How does Spring MVC map an HTTP request to a controller method?

MediumAmazon
5

How would you handle a multipart file upload in a REST controller?

MediumRazorpay

Ask Aria about REST Controllers

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…