Mastering Spring Boot Web & REST Annotations: A Complete Guide with Examples

3 min read

Mastering Spring Boot Web & REST Annotations: A Complete Guide with Examples

1. Introduction

In modern web development, Spring Boot has become a go-to framework for building robust and scalable RESTful APIs. One of the main reasons for its popularity lies in its annotation-driven programming model, which greatly simplifies the process of mapping web requests to backend logic.

In this article, we will explore how Web and REST annotations such as @RequestMapping, @GetMapping, @PostMapping, @PathVariable, @RequestParam, @RequestBody, and @ResponseBody are used to create a fully functional REST API in Spring Boot.


2. Problem

When building APIs, developers often face repetitive and verbose configurations to map HTTP requests (like GET, POST, PUT, DELETE) to Java methods. Before Spring Boot’s annotation-based approach, developers had to manually configure these routes and parse request parameters, making the code harder to maintain and understand.

  • The controller code becomes cluttered with boilerplate.
  • It’s harder to distinguish different HTTP methods.
  • Managing path variables and query parameters becomes error-prone.

3. Solution

Spring Boot’s annotation model solves these problems by providing declarative annotations that map web requests directly to Java methods. These annotations allow developers to specify request paths, HTTP methods, and parameters in a concise and readable way.

  • @RequestMapping → defines the base mapping and HTTP method types.
  • @GetMapping, @PostMapping, etc. → simplified versions of @RequestMapping for specific HTTP methods.
  • @PathVariable and @RequestParam → extract path and query parameters.
  • @RequestBody → maps request payloads to Java objects.
  • @ResponseBody → sends method results back as JSON or XML.

This makes building RESTful services clean, modular, and easy to maintain.


4. Implementation

Let’s walk through an example of a simple Spring Boot REST controller that demonstrates each annotation.

Step 1: Define a Model Class

package com.example.demo.model;

public class Product {
    private Long id;
    private String name;
    private double price;

    // Constructors
    public Product() {}
    public Product(Long id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    // Getters and Setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
}

Step 2: Create a REST Controller

package com.example.demo.controller;

import com.example.demo.model.Product;
import org.springframework.web.bind.annotation.*;
import java.util.*;

@RestController
@RequestMapping("/api/products") // Base path for all endpoints in this controller
public class ProductController {

    private Map<Long, Product> productRepo = new HashMap<>();

    // Sample data
    public ProductController() {
        productRepo.put(1L, new Product(1L, "Laptop", 1200.00));
        productRepo.put(2L, new Product(2L, "Phone", 800.00));
    }

    // @GetMapping - Retrieve all products
    @GetMapping
    public Collection<Product> getAllProducts() {
        return productRepo.values();
    }

    // @GetMapping with @PathVariable - Retrieve product by ID
    @GetMapping("/{id}")
    public Product getProductById(@PathVariable Long id) {
        return productRepo.get(id);
    }

    // @GetMapping with @RequestParam - Filter products by minimum price
    @GetMapping("/filter")
    public Collection<Product> filterByPrice(@RequestParam double minPrice) {
        List<Product> result = new ArrayList<>();
        for (Product p : productRepo.values()) {
            if (p.getPrice() >= minPrice) result.add(p);
        }
        return result;
    }

    // @PostMapping with @RequestBody - Create new product
    @PostMapping
    public Product createProduct(@RequestBody Product product) {
        productRepo.put(product.getId(), product);
        return product;
    }

    // @PutMapping - Update product
    @PutMapping("/{id}")
    public Product updateProduct(@PathVariable Long id, @RequestBody Product updatedProduct) {
        productRepo.put(id, updatedProduct);
        return updatedProduct;
    }

    // @DeleteMapping - Delete product
    @DeleteMapping("/{id}")
    public String deleteProduct(@PathVariable Long id) {
        productRepo.remove(id);
        return "Product with ID " + id + " deleted successfully.";
    }
}

Explanation of Annotations

AnnotationDescription
@RestControllerCombines @Controller and @ResponseBody. Indicates that this class handles REST requests.
@RequestMapping("/api/products")Defines the base path for all methods in the controller.
@GetMappingHandles HTTP GET requests (data retrieval).
@PostMappingHandles HTTP POST requests (data creation).
@PutMappingHandles HTTP PUT requests (data updates).
@DeleteMappingHandles HTTP DELETE requests (data deletion).
@PathVariableExtracts dynamic values from the URI path.
@RequestParamReads query parameters like ?minPrice=100.
@RequestBodyMaps JSON request bodies to Java objects automatically.
@ResponseBodyReturns the method’s return value directly as the HTTP response body (applied automatically by @RestController).

5. Conclusion

Spring Boot’s Web and REST annotations make API development intuitive and efficient. By simply annotating methods, developers can map HTTP requests, handle dynamic paths, process query parameters, and serialize/deserialize request bodies without writing extra boilerplate code.

These annotations are the foundation of modern RESTful microservices built with Spring Boot — keeping controllers clean, readable, and easy to maintain.

🤞 Never miss a story from us, get weekly updates to your inbox!

Leave a Reply

Your email address will not be published. Required fields are marked *