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
GETrequest to/employeesshould return a list of all employees. - A
POSTrequest to/employeesshould 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:
- Get all resources: A
GETrequest to/employeesreturns a list of all employees. - Get a single resource by ID: A
GETrequest to/employees/{id}returns the specific employee with that ID. To capture theidfrom the URL, we use the@PathVariableannotation.
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:
- Create a new blog post.
- Retrieve a specific blog post by its unique title.
- 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
- Create a new blog post:
- Method:
POST - Annotation:
@PostMapping - Path:
/posts
- Method:
- Retrieve a specific blog post by its title:
- Method:
GET - Annotation:
@GetMapping - Path:
/posts/{title}(The title would be a path variable).
- Method:
- Retrieve all comments for a specific post:
- Method:
GET - Annotation:
@GetMapping - Path:
/posts/{postId}/comments(Here,postIdidentifies the post for which we want comments).
- Method:
C. Update and Delete: @PutMapping and @DeleteMapping
Finally, to complete our CRUD functionality, we need to handle updates and deletions.
@PutMapping: MapsPUTrequests, used to update an existing resource. LikePOST, it often uses@RequestBodyfor the updated data and@PathVariableto identify which resource to update.@DeleteMapping: MapsDELETErequests, 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.
-
Create an
Employeeclass: In a new packagecom.mybackend.firstapi.model, create a simpleEmployeeclass. 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; } -
Create the
EmployeeController: In yourcontrollerpackage, create a newEmployeeControllerclass. -
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
Listand 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! } -
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
PUTmethod, find the employee and update their fields. ForDELETE, find and remove them from the list. -
Test Your API: Run your application. Since only
GETrequests can be easily made from a browser, you will need an API client like Postman to testPOST,PUT, andDELETE. 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. @GetMappingis for reading data.@PostMappingis for creating new data.@PutMappingis for updating existing data.@DeleteMappingis for deleting data.- Annotations like
@RequestBodyand@PathVariableare 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.