Start Learning
Javaneer
Back to stage
Module 2·Building Web APIs

REST Controllers & Mapping

@RestController, mapping URLs and HTTP methods, path variables and query params, and ResponseEntity.

18 min readIntermediate
On this page

Now that you know how a request flows through Spring MVC, let's write the controllers that handle it. A REST controller maps HTTP verbs and URLs to Java methods - this is the surface of BookVault's API.

@RestController and mappings

@RestController marks a class as a web handler whose return values become response bodies. @RequestMapping sets a base path; the verb-specific annotations map methods:

@RestController
@RequestMapping("/api/books")
class BookController {

    @GetMapping                       // GET /api/books
    List<Book> all() { ... }

    @GetMapping("/{isbn}")            // GET /api/books/{isbn}
    Book byIsbn(@PathVariable String isbn) { ... }

    @PostMapping                      // POST /api/books
    Book add(@RequestBody Book book) { ... }

    @PutMapping("/{isbn}")            // PUT /api/books/{isbn}
    Book replace(@PathVariable String isbn, @RequestBody Book book) { ... }

    @DeleteMapping("/{isbn}")         // DELETE /api/books/{isbn}
    void remove(@PathVariable String isbn) { ... }
}

The verb carries meaning: GET reads, POST creates, PUT replaces, DELETE removes. Following these conventions is what makes an API "RESTful."

Path variables vs query parameters

Two ways to receive input from the URL, for two different purposes:

// Path variable — identifies a specific resource
@GetMapping("/{isbn}")
Book byIsbn(@PathVariable String isbn) { ... }         // GET /api/books/978-013...

// Query parameter — filters, sorts, paginates a collection
@GetMapping
List<Book> search(@RequestParam(required = false) String author) { ... }
//                                                                     GET /api/books?author=Bloch

Path for identity, query for options

A rule of thumb: if it identifies which resource, it's a path variable (/books/{isbn}). If it filters or shapes a collection, it's a query parameter (?author=Bloch&sort=title). Getting this right makes URLs predictable.

Controlling the status code with ResponseEntity

By default a @RestController method returns 200 OK. But creating a resource should return 201 Created, and some responses need custom headers. ResponseEntity gives you full control of status, headers, and body:

@PostMapping
ResponseEntity<Book> add(@RequestBody Book book) {
    Book saved = service.add(book);
    return ResponseEntity
        .status(HttpStatus.CREATED)              // 201, not 200
        .header("Location", "/api/books/" + saved.isbn())
        .body(saved);
}
Verbs are the API's grammar

An HTTP API is a little language: the noun is the URL (/api/books/{isbn}), and the verb is the method (GET, POST, PUT, DELETE). "GET the book," "DELETE the book." When you respect that grammar, any developer - or tool - can read your API without a manual, because the sentences follow rules everyone already knows.

Design the routes

BookVault needs these operations. Give the HTTP method + path for each, and say whether any input is a path variable or a query parameter:

  1. List all books.
  2. Get one book by its ISBN.
  3. Add a new book.
  4. Find books by a given author.
  5. Delete a book by ISBN.

When should a value be a @PathVariable rather than a @RequestParam?

Key takeaways

  • @RestController + @RequestMapping define an API; @GetMapping/@PostMapping/@PutMapping/@DeleteMapping map HTTP verbs to methods.
  • Follow REST conventions: GET reads, POST creates, PUT replaces, DELETE removes.
  • @PathVariable captures resource identity (/books/{isbn}); @RequestParam captures filters/options (?author=Bloch).
  • Return ResponseEntity to control the status code (e.g. 201 Created), headers, and body.
  • A well-designed API reads like a sentence: verb (method) + noun (URL).
Was this lesson helpful?
Edit this page on GitHub