Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 17

Mapping HTTP Methods to Controller Actions

Recommended resources

Hello! Welcome to our next lesson.

In our last session, we created our first API endpoint using @RestController and the general-purpose @RequestMapping annotation. You saw that when you make a request to /greeting, your Java code executes and returns a message. This is a great start, but in real-world REST APIs, we need to be more specific about how a client can interact with a URL.

This lesson focuses on implementing the four core actions of any data-driven application: Create, Read, Update, and Delete (CRUD). You will learn how to implement HTTP methods (GET, POST, PUT, DELETE) using specific mapping annotations. By the end of this lesson, you'll be able to build a controller that can manage a resource completely.

1. From General to Specific: Why We Need More Than @RequestMapping

In the previous lesson, we used @RequestMapping("/greeting"). By default, this annotation maps to all HTTP methods. This means a client could technically send a GET, POST, PUT, or DELETE request to that URL, and the same getGreeting() method would be triggered.

For a robust and predictable API, this is not ideal. We want different actions to be handled by different methods. For example:

  • A GET request to /employees should return a list of all employees.
  • A POST request to /employees should create a new employee.

To achieve this, Spring provides specific annotations that are shortcuts for @RequestMapping pre-configured with a specific HTTP method.

Spring @RequestMapping New Shortcut Annotations

This article from Baeldung clearly explains why these new shortcut annotations were introduced and how they work under the hood.

Read the sections '1. Overview' and '3. How It Works'. Focus on understanding that annotations like @GetMapping are simply more readable, specialized versions of the original @RequestMapping annotation.

As the article explains, the primary annotations we will use for our REST controllers are:

  • @GetMapping: For retrieving resources (Read).
  • @PostMapping: For creating new resources (Create).
  • @PutMapping: For updating existing resources (Update).
  • @DeleteMapping: For deleting resources (Delete).

Using these makes your code self-documenting and less prone to errors.


2. Building a CRUD API: A Practical Walkthrough

Theory is great, but the best way to learn is by doing. We are now going to build a full set of CRUD endpoints for managing a list of employees. The following video provides a comprehensive walkthrough.

While the video implements a complete application with service and repository layers, our focus for today is solely on the EmployeeController class. Pay close attention to the annotations used for each method.

Java, Spring Boot, PostgreSQL, Spring Data JPA, Hibernate CRUD REST API Tutorial [2025]

The Java Guides channel provides an excellent, step-by-step tutorial for building a CRUD REST API. We will watch it in segments to implement each of the four operations.

You will watch this video in parts as we go through each HTTP method. For now, just be ready to follow along.

A. Create: @PostMapping

To add a new resource to our system, we use the POST method. The @PostMapping annotation maps incoming HTTP POST requests to a handler method.

When creating a resource, the client usually sends the data for the new resource (e.g., the new employee's details) in the request body, typically as a JSON object. We use the @RequestBody annotation to tell Spring to convert this JSON into a Java object.

Java, Spring Boot, PostgreSQL, Spring Data JPA, Hibernate CRUD REST API Tutorial [2025]

Let's start by implementing the 'Create' operation. Watch this segment to see how to build a POST endpoint.

Watch from 00:22:27 to 00:32:43. Focus on the EmployeeController and notice the use of @PostMapping and @RequestBody.

B. Read: @GetMapping

To retrieve resources, we use the GET method. We can use @GetMapping in two common ways:

  1. Get all resources: A GET request to /employees returns a list of all employees.
  2. Get a single resource by ID: A GET request to /employees/{id} returns the specific employee with that ID. To capture the id from the URL, we use the @PathVariable annotation.

Now, let's watch how to implement both of these "Read" operations.

Java, Spring Boot, PostgreSQL, Spring Data JPA, Hibernate CRUD REST API Tutorial [2025]

Next, we'll implement the 'Read' operations. This part of the video covers fetching a single employee and all employees.

Watch from 00:32:43 to 00:47:08. Pay attention to how @GetMapping is used for two different URLs and how @PathVariable is used to extract the ID from the URL path.

Note: We'll dive deeper into @RequestBody and @PathVariable in upcoming lessons. For today, just understand their basic roles in getting data into our methods.

Test your understanding!

You are designing an API for a blog. You need endpoints to:

  1. Create a new blog post.
  2. Retrieve a specific blog post by its unique title.
  3. Retrieve all comments for a specific post.

Which HTTP method and mapping annotation would you use for each task? What would the URL paths look like?

Show answer
  1. Create a new blog post:
    • Method: POST
    • Annotation: @PostMapping
    • Path: /posts
  2. Retrieve a specific blog post by its title:
    • Method: GET
    • Annotation: @GetMapping
    • Path: /posts/{title} (The title would be a path variable).
  3. Retrieve all comments for a specific post:
    • Method: GET
    • Annotation: @GetMapping
    • Path: /posts/{postId}/comments (Here, postId identifies the post for which we want comments).

C. Update and Delete: @PutMapping and @DeleteMapping

Finally, to complete our CRUD functionality, we need to handle updates and deletions.

  • @PutMapping: Maps PUT requests, used to update an existing resource. Like POST, it often uses @RequestBody for the updated data and @PathVariable to identify which resource to update.
  • @DeleteMapping: Maps DELETE requests, used to remove a resource, typically identified by a @PathVariable.

Let's watch the final segment to complete our controller.

Java, Spring Boot, PostgreSQL, Spring Data JPA, Hibernate CRUD REST API Tutorial [2025]

Let's implement the 'Update' and 'Delete' operations.

Watch from 00:47:08 to 01:00:19. Observe the use of @PutMapping and @DeleteMapping, noting how they both use @PathVariable to specify the target employee.


3. Hands-On: Build Your Own CRUD Controller

Now it's your turn to apply what you've learned to your first-api project. We'll create a simplified EmployeeController that stores data in memory (in a simple List) to keep the focus on the API layer.

  1. Create an Employee class: In a new package com.mybackend.firstapi.model, create a simple Employee class. Since you know Java well, you can start with a basic structure for an employee record. For example:

    package com.mybackend.firstapi.model;
    
    // Add constructors, getters, and setters
    public class Employee {
        private long id;
        private String firstName;
        private String lastName;
        private String email;
    }
    
  2. Create the EmployeeController: In your controller package, create a new EmployeeController class.

  3. Implement the Controller Logic: Use the video and the code snippet below as a guide to build out your controller. Instead of a database, we'll use a List and a simple counter to manage IDs.

    package com.mybackend.firstapi.controller;
    
    import com.mybackend.firstapi.model.Employee;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicLong;
    
    @RestController
    @RequestMapping("/api/employees") // Base path for all methods in this controller
    public class EmployeeController {
    
        private final List<Employee> employees = new ArrayList<>();
        private final AtomicLong counter = new AtomicLong();
    
        public EmployeeController() {
            // Pre-populate with some data
            employees.add(new Employee(counter.incrementAndGet(), "John", "Doe", "john.doe@example.com"));
            employees.add(new Employee(counter.incrementAndGet(), "Jane", "Smith", "jane.smith@example.com"));
        }
    
        // 1. GET all employees
        @GetMapping
        public List<Employee> getAllEmployees() {
            return employees;
        }
    
        // 2. POST a new employee
        // Use Postman or a similar tool to send a POST request to http://localhost:8080/api/employees
        // with a JSON body like: {"firstName": "Sam", "lastName": "Jones", "email": "sam.j@email.com"}
        @PostMapping
        public Employee createEmployee(@RequestBody Employee newEmployee) {
            newEmployee.setId(counter.incrementAndGet());
            employees.add(newEmployee);
            return newEmployee;
        }
    
        // Add methods for GET by ID, PUT, and DELETE here.
        // Challenge yourself to write them based on the video and the patterns you've seen!
    }
    
    
  4. Complete the Controller: Add the methods for:

    • GET /api/employees/{id}
    • PUT /api/employees/{id}
    • DELETE /api/employees/{id}

    You'll need to find the employee in the list for these operations. For the PUT method, find the employee and update their fields. For DELETE, find and remove them from the list.

  5. Test Your API: Run your application. Since only GET requests can be easily made from a browser, you will need an API client like Postman to test POST, PUT, and DELETE. This is an essential tool for backend developers.


4. A Clean Example

You've now seen how the pieces fit together. For a final, clean reference, the official Spring guide provides a concise example of a complete controller.

Getting Started | Building REST services with Spring

Let's look at the official Spring guide's EmployeeController. This is a great example of what a finished, simple REST controller looks like.

Review the code for EmployeeController.java under the 'HTTP is the Platform' section. Notice how each method corresponds to a specific action and HTTP verb, all organized neatly within one class.


Conclusion

Excellent work today! You have made a huge leap from a single, simple endpoint to building a controller that can perform all the fundamental CRUD operations.

Key Takeaways:

  • For clear and maintainable REST APIs, use specific mapping annotations: @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping.
  • @GetMapping is for reading data.
  • @PostMapping is for creating new data.
  • @PutMapping is for updating existing data.
  • @DeleteMapping is for deleting data.
  • Annotations like @RequestBody and @PathVariable are used to get data from the incoming request, which is essential for making your endpoints dynamic.

What's Next?

In this lesson, we briefly introduced @RequestBody and @PathVariable out of necessity. They are crucial for handling client data. In our next lesson, we will focus entirely on handling request and response bodies using @RequestBody and @ResponseBody. You'll gain a much deeper understanding of how Spring deserializes incoming JSON into Java objects and serializes your Java objects back into JSON for the response.