Master Spring Boot 2.x: Build RESTful APIs with @RestController and Unit Tests

This tutorial walks you through Spring Boot 2.x fundamentals, explaining core MVC annotations, defining a User entity with Lombok, creating a full RESTful CRUD controller, and writing comprehensive MockMvc unit tests to verify each endpoint.

Programmer DD
Programmer DD
Programmer DD
Master Spring Boot 2.x: Build RESTful APIs with @RestController and Unit Tests

First, review the key Spring MVC annotations used in the quick‑start tutorial: @Controller, @RestController, and @RequestMapping. If you are unfamiliar with Spring MVC, read the quick‑start guide before proceeding. @Controller: marks a class as an HTTP request handler. @RestController: combines @Controller and @ResponseBody, returning JSON by default. @RequestMapping: configures URL mapping; newer method‑specific annotations such as GetMapping, PostMapping, DeleteMapping, and PutMapping are now preferred.

We then implement a RESTful API for managing User objects using Spring MVC, demonstrating request mapping, parameter binding, and unit testing.

Define User Entity

@Data
public class User {

    private Long id;
    private String name;
    private Integer age;
}

The @Data annotation from Lombok automatically generates getters, setters, and other boilerplate methods. Add the Lombok dependency to your pom.xml:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

Implement User Operations Controller

@RestController
@RequestMapping(value = "/users") // all mappings under /users
public class UserController {

    // thread‑safe map simulating storage
    static Map<Long, User> users = Collections.synchronizedMap(new HashMap<>());

    @GetMapping("/")
    public List<User> getUserList() {
        return new ArrayList<>(users.values());
    }

    @PostMapping("/")
    public String postUser(@RequestBody User user) {
        users.put(user.getId(), user);
        return "success";
    }

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return users.get(id);
    }

    @PutMapping("/{id}")
    public String putUser(@PathVariable Long id, @RequestBody User user) {
        User u = users.get(id);
        u.setName(user.getName());
        u.setAge(user.getAge());
        users.put(id, u);
        return "success";
    }

    @DeleteMapping("/{id}")
    public String deleteUser(@PathVariable Long id) {
        users.remove(id);
        return "success";
    }
}
Compared with the 1.x tutorial, the newer version replaces the generic @RequestMapping with method‑specific annotations ( @GetMapping , @PostMapping , etc.) and uses @RequestBody for JSON payloads instead of @ModelAttribute .

Write Unit Tests

The following test class uses MockMvc to verify each CRUD operation:

@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter21ApplicationTests {

    private MockMvc mvc;

    @Before
    public void setUp() {
        mvc = MockMvcBuilders.standaloneSetup(new UserController()).build();
    }

    @Test
    public void testUserController() throws Exception {
        // 1. GET empty list
        mvc.perform(get("/users/"))
           .andExpect(status().isOk())
           .andExpect(content().string(equalTo("[]")));

        // 2. POST a user
        mvc.perform(post("/users/")
           .contentType(MediaType.APPLICATION_JSON)
           .content("{\"id\":1,\"name\":\"Test Master\",\"age\":20}"))
           .andExpect(content().string(equalTo("success")));

        // 3. GET list with the new user
        mvc.perform(get("/users/"))
           .andExpect(status().isOk())
           .andExpect(content().string(equalTo("[{\"id\":1,\"name\":\"Test Master\",\"age\":20}]")));

        // 4. PUT to update the user
        mvc.perform(put("/users/1")
           .contentType(MediaType.APPLICATION_JSON)
           .content("{\"name\":\"Ultimate Master\",\"age\":30}"))
           .andExpect(content().string(equalTo("success")));

        // 5. GET the updated user
        mvc.perform(get("/users/1"))
           .andExpect(content().string(equalTo("{\"id\":1,\"name\":\"Ultimate Master\",\"age\":30}")));

        // 6. DELETE the user
        mvc.perform(delete("/users/1"))
           .andExpect(content().string(equalTo("success")));

        // 7. GET empty list again
        mvc.perform(get("/users/"))
           .andExpect(status().isOk())
           .andExpect(content().string(equalTo("[]")));
    }
}

For MockMvc users, remember to import the static helper methods:

import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

By adding the spring-boot-starter-web dependency (no extra configuration needed), you can quickly create a fully functional RESTful API for the User entity and verify it with comprehensive unit tests. The tutorial also highlights the most common Spring MVC annotations: @RestController, @RequestMapping, @PathVariable, and @RequestBody.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javaunit testingSpring BootSpring MVCLombokRESTful API
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.