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.

CRUD App in Spring Boot

Prerequisites:

To complete this tutorial, you will need to have below things:


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:

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.

Mlab Home Page
MongoDB Deployment
Select Cloud Provider and Plan Type
Select Region
Enter Database Name

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.

DB URI
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.

Mlab DB User Creation


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:

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:

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);
    }
}


APIs Call from Postman:
Create User:
Create User

Get All Users:
Get All Users
Get User:
Get User
Update User:
Update User
Delete 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.


Leave a Reply

Your email address will not be published. Required fields are marked *