Step-by-Step: Building a CRUD API with Spring Boot
What Are CRUD Operations?
CRUD operations are fundamental in software development and database management, and they serve as a foundation for various applications and systems that involve data manipulation. Many programming languages, frameworks, and databases provide tools and APIs to perform these operations easily and securely. CRUD is an acronym that stands for Create, Read, Update, and Delete. These operations are essential for managing and manipulating data:
Create(C): This operation involves the creation of new data records or objects in a database. It typically involves inserting new data into a database table or adding new resources in an application.
Read (R): The “Read” operation is about retrieving and reading data from a database or resource. It allows you to access and view existing data without modifying it. In database terms, this is often done through queries, and in software applications, it’s akin to reading information from a file or an API.
Update (U): This operation is used to modify or update existing data. You can use it to change the attributes or properties of an object or to update records in a database table. It is typically used to keep data up to date.
Delete (D): The “Delete” operation involves removing data or objects from a database or application. It’s used when you want to eliminate unnecessary or outdated information.
Rest API To Perform CRUD Using Spring Boot
Creating a CRUD (Create, Read, Update, Delete) API with Spring Boot in Java is a common task for building web applications.
Below, I’ll provide a step-by-step tutorial on how to create a simple CRUD API for a simple banking system to create users and accounts for users using Spring Boot:
Step 1: Set Up Our Development Environment → Make sure we have the following tools installed:
Java Development Kit (JDK)
Integrated Development Environment (IDE) like IntelliJ IDEA or Eclipse
Maven
Step 2: Create a Spring Boot Project
We can use Spring Initializr to quickly bootstrap a Spring Boot project. Visit the Spring Initializr website (https://start.spring.io/) and configure your project with the following settings:
Project: Choose “Maven Project”
Language: Choose “Java”
Spring Boot: Choose a version (e.g., 3.1.4)
Group: Your package name (e.g., com.example)
Artifact: Your project name (e.g., spring-boot-crud-api)
Dependencies: Add “Spring Web,” “Spring Data JPA,” and “H2” (in-memory database for this example)
Click “Generate” to download the project structure as a zip file. Extract it to your preferred directory.
Step 3: Configure the Application
Open the src/main/resources/application.yml
or src/main/resources/application.properties
file and configure the database settings. For the H2 database (for testing purposes), we can use the following:
spring:
datasource:
url: jdbc:h2:mem:testdb
driverClassName: org.h2.Driver
username: sa
password: password
jpa:
hibernate.ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect
Step 4: Define the Model
Create model classes to represent essential entities like User
and Account
.
// User
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Table(name="USER_DETAILS")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
private String username;
@NotBlank
private String password;
private String email;
private String name;
}
// Account
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Table(name="ACCOUNT")
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger id;
@NotNull
private Long userId;
private double balance;
}
Step 5: Create Repositories
Create JPA repositories for the User
and Account
entities. Spring Data JPA will provide default CRUD methods for these repositories:
// User Repository
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
// Account Repository
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface AccountRepository extends JpaRepository<Account, Long> {
List<Account> findByUserId(Long userId);
}
Step 6: Create Controllers
Implement controllers for user creation, account creation, and other CRUD operations.
// Controller To Perform CRUD Operations Related To User
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping
public User createUser(@RequestBody User user) {
return userService.createUser(user);
}
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User updatedUser) {
return userService.updateUserDetails(id, updatedUser);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
}
In the above UserController, we will perform the following CRUD operations:
The
getAllUsers:
method uses aGET
request to retrieve a list of all users.The
getUserById
method retrieves a user by their uniqueid
.The
createUser
method uses aPOST
request to create a new user.The
updateUser
method uses aPUT
request to update an existing user's details.The
deleteUser
method uses aDELETE
request to delete a user by theirid
.
// Controller To Perform CRUD Operations Related To Account Of An User
@RestController
@RequestMapping("/api/accounts")
public class AccountController {
private final AccountService accountService;
@Autowired
public AccountController(AccountService accountService) {
this.accountService = accountService;
}
@GetMapping("/{userId}")
public List<Account> getUserAccounts(@PathVariable Long userId) {
return accountService.getUserAccounts(userId);
}
@PostMapping
public Account createAccount(@RequestBody Account account) {
return accountService.createAccount(account);
}
@GetMapping("/{accountId}")
public Account getAccountById(@PathVariable Long accountId) {
return accountService.getAccountById(accountId);
}
@PutMapping("/{accountId}")
public Account updateAccount(@PathVariable Long accountId, @RequestBody Account updatedAccount) {
return accountService.updateAccountDetails(accountId, updatedAccount);
}
@DeleteMapping("/{accountId}")
public void deleteAccount(@PathVariable Long accountId) {
accountService.deleteAccount(accountId);
}
}
In this AccountController,
we will perform the following CRUD operations:
The
getUserAccounts
method retrieves a list of accounts associated with a user, given theuserId
.The
createAccount
method allows creating a new account for an user.The
getAccountById
method retrieves an account by its uniqueaccountId
.The
updateAccount
method is used to update account details.The
deleteAccount
method allows deleting an account by its uniqueaccountId
.
Step 7: Run And Test Spring Boot CRUD API
Execute the below command to start the application or Run the main class of the application in IDE:
mvn spring-boot:run
Once the application is up and running we will see below logs:
We can use tools like Postman or cURL to test the application. Ensure you have proper authentication and authorization mechanisms in place to protect sensitive data.
I have used Postman to test the API as shown below with sample requests and responses for each API:
- Create User:
Create a user with the below request:
{
"username": "reetesh",
"password": "password123",
"email": "reet.test@test.com",
"name": "Spring Boot Crud Demo"
}
2. List All the Users:
Get all the users created from the database.
3. Get A User By User ID:
In the below sample, we have fetched a user with userId 1.
4. Create an Account For A User
5. Get Account By Account ID
6. Update Account
Let's update the balance of the newly created account with accountID 1. After the successful update account balance is 2000.00.
Similarly, we can perform other CRUD operations for users and accounts.
Conclusion
That’s it! We’ve created a basic CRUD API using Spring Boot. We can further extend and customize this example to meet our specific requirements. The complete source code for this article can be found on GitHub.
Happy Learning !!!