In the previous tutorial, we learned How to create a Spring Boot App with Spring Initializr and Maven. In this tutorial, we will learn how to create a CRUD (Create, Read, Update, Delete) App in Spring Boot. In this tutorial, we will create a CRUD HTTP Rest APIs for user management
. In this tutorial, we will use the project setup code from the previous article and create a separate repo. Please fork the spring boot starter app from Github.
Prerequisites:
To complete this tutorial, you will need to have below things:
- Java should be installed in the development system.
- Maven should be installed in the development system.
- IntelliJ IDEA installed in the development system.
- Postman: API Development Tool.
- Fork the Spring Boot Starter App.
Spring Boot CRUD App:
In this tutorial, we will create the CRUD (Create, Read, Update, Delete) functionality in the User Management App. We will create users, read all the info of the user data, update the user info, and delete the single user or delete the all user list. In this tutorial, we will use MongoDB as the Database.
Project Structure:
Setting up Database in Mlab:
We will use Mlab as the cloud based MongoDB database. Now Mlab is the part of MongoDB, Inc.
- Log in to Mlab account.
- Create a new MongoDB Deployment by click on Create new Button. After that, you will redirect to the next page. On that page, you will select Cloud Provider. Mlab having three top cloud providers (Amazon Web Services, Google Cloud Platform, Microsoft Azure). You will select anyone from them. I’m selecting AWS (Amazon Web services). After that, we will select the plan type. I recommended Sandbox because it’s free for 500MB.
- After that, you will select the region. Please select the region, which is near to your country. I’m selecting Europe(Ireland)(eu-west-1).
- The last step is Final details. In this step you will give the database name like spring-user-management.
Udate application.properties :
After creating the database in Mlab, the we will update the application.properties
file. We will add database URI, which we will get from Mlab by clicking on created database, in application.properties
.
spring.data.mongodb.uri = mongodb://<dbuser>:<dbpassword>@{DB_URI}?retryWrites=false
In this place of dbuser and dbpassword, you will write the user and password detail to the database. You will get both details, when you will create a database user by click on Add Database User under the User tab in the Database.
Create User Model :
This model class is created for the user entity and map to the user collection in the database. @Document()
is used to map the class with collection in the database. value
argument is used for declaring the collection name. @Id
is used for declaring the _id key of the document.
package com.thedevfamily.usermanagement.model; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document(value = "user") public class User { @Id private String _id; private String username; private String firstName; private String lastName; private String email; public User(String _id, String username, String firstName, String lastName, String email) { this._id = _id; this.username = username; this.firstName = firstName; this.lastName = lastName; this.email = email; } public String get_id() { return _id; } public void set_id(String _id) { this._id = _id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User{" + "_id='" + _id + '\'' + ", username='" + username + '\'' + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", email='" + email + '\'' + '}'; } }
Create Repository Interface:
The Repository follows the Spring Data-Centric approach and comes with more flexible operations. We will create UserRepository
for access the User
data from the database. In this repository, we will use Spring Data MongoRepository that provides us the common functionalities. We will extend the MongoRepository
and use all these common functionalities.
Below code will create UserRepository
package com.thedevfamily.usermanagement.repository; import com.thedevfamily.usermanagement.model.User; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends MongoRepository<User, String> { }
Create Data Access Layer (DAL):
We will create the Data Access Layer for accessing and working with database. By creating this we will access the database with ease. To provide the data access in the spring app, we will create an Interface named UserService
.
package com.thedevfamily.usermanagement.service; import com.thedevfamily.usermanagement.model.User; import java.util.List; import java.util.Optional; public interface UserService { User createUser(User userDetails); List<User> getAllUsers(); Optional<User> getUser(String id); Optional<User> deleteUser(String id); User updateUser(User userDetails, String id); }
Implementing Data Access Layer Interface :
In this section, we will create methods for DAL Interface like:
createUser()
getAllUsers()
getUser()
deleteUser()
updateUser()
package com.thedevfamily.usermanagement.service; import com.mongodb.MongoException; import com.thedevfamily.usermanagement.model.User; import com.thedevfamily.usermanagement.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class UserServiceImpl implements UserService { @Autowired UserRepository userRepository; @Override public User createUser(User userDetails) { User user = new User(userDetails.getUsername(), userDetails.getFirstName(),userDetails.getLastName(),userDetails.getEmail()); return userRepository.save(user); } @Override public List<User> getAllUsers() { return userRepository.findAll(); } @Override public Optional<User> getUser(String id) { return userRepository.findById(id); } @Override public Optional<User> deleteUser(String id) { Optional<User> fetchedUser = userRepository.findById(id); if(fetchedUser.isPresent()) userRepository.deleteById(id); return fetchedUser; } @Override public User updateUser(User userDetails, String id) { if(userRepository.findById(id).isPresent()) { User existingUser = userRepository.findById(id).get(); if (userDetails.getFirstName() != null) existingUser.setFirstName(userDetails.getFirstName()); if (userDetails.getLastName() != null) existingUser.setLastName(userDetails.getLastName()); if (userDetails.getUsername() != null) existingUser.setUsername(userDetails.getUsername()); if (userDetails.getEmail() != null) existingUser.setEmail(userDetails.getEmail()); return userRepository.save(existingUser); } else throw new MongoException("Record not found"); } }
In UserServiceImpl
, we will autowired the UserRepository
for access the database in spring application.
Create Controller Class :
Let’s finally, we will create a Controller Class that handles all the business logic of the application. We will create UserController
class and autowired the UserService
. In this controller class, we will create methods for each APIs like:
- createUser () for
http://localhost:8080/user/api/v1/create
- getAllUsers() for
http://localhost:8080/user/api/v1/users
- getUser() for
http://localhost:8080/user/api/v1/users/{id}
- deleteUser() for
http://localhost:8080/user/api/v1/users/{id}
- updateUser() for
http://localhost:8080/user/api/v1/users/{id}
package com.thedevfamily.usermanagement.controller; import com.thedevfamily.usermanagement.model.User; import com.thedevfamily.usermanagement.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; @RestController @RequestMapping(value = "user/api/v1/") public class UserController { @Autowired UserService userService; @RequestMapping(value = "create", method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) public ResponseEntity<User> createUser(@RequestBody User userDetails){ User user = new User(userDetails.getUsername(), userDetails.getFirstName(),userDetails.getLastName(),userDetails.getEmail()); User savedUser = userService.createUser(user); return new ResponseEntity<>(savedUser, HttpStatus.CREATED); } @RequestMapping(value = "users", method = RequestMethod.GET) @ResponseStatus(HttpStatus.OK) public ResponseEntity<List<User>> getAllUsers() { return new ResponseEntity<List<User>>(userService.getAllUsers(), HttpStatus.OK); } @RequestMapping(value = "user/{id}", method = RequestMethod.GET) @ResponseStatus(HttpStatus.OK) public ResponseEntity<Optional<User>> getUser(@PathVariable(value = "id") String id) { Optional<User> getUser = userService.getUser(id); return new ResponseEntity<Optional<User>>(getUser, HttpStatus.OK); } @RequestMapping(value = "user/{id}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.OK) public ResponseEntity<Optional<User>> deleteUser(@PathVariable(value = "id") String id) { Optional<User> getUser = userService.deleteUser(id); return new ResponseEntity<Optional<User>>(getUser, HttpStatus.OK); } @RequestMapping(value = "user/{id}", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.OK) public ResponseEntity<User> updateUser(@RequestBody User usedDetails, @PathVariable(value = "id") String id ){ return new ResponseEntity<>(userService.updateUser(usedDetails, id), HttpStatus.OK); } }
- @RestController annotation is used for creating the RESTful Controller. It includes @Controller and @ResponseBody annotation.
- @RequestMapping annotation is used for mapping the HTTP request with class methods. This annotation will be declared at the class level and method level.
- @ResponseStatus will use for the HTTP method. It will handle the HTTP method in the application.
- @RequestBody annotation will use for taking payload from the API.
- @ResponseEntity having all data about a response like headers, body, status code, etc.
- @PathVariable having the template variable of the URI.
APIs Call from Postman:
Create User:
Get All Users:
Get User:
Update User:
Delete User:
Conclusion:
In the above tutorial, we learned how to create a CRUD App using Spring boot and MongoDB. Please find the code in Github Repo. In the next tutorial, I will implement Exception Handling, Centralized Logging System with ELK Stack, and containerization with Docker.
If you have any doubt, please reach out by email: developer@thedevfamily.com.