Spring boot and MongoDB REST API CRUD Tutorial [Updated 2021]





Hey, guys in this, we will learn connecting the spring boot REST API that connects to the MongoDB database and we will perform the basic database operations like Create, Read, Update and Delete.

Development steps


Following are the development steps to create a spring boot application and connect to the mongodb database

Create a spring boot project using Spring Initializr


Create a spring boot using spring initializr and add the following the dependencies

  • Web
  • Spring Data MongoDB
  • Devtools
  • Lombok
  • Validation

Setting up the MongoDB database


Download and install the MongoDB database locally on your machine from the following URL

  • https://www.mongodb.com/try/download/community





Next, in order to connect to the MongoDB database, we need a GUI tool that will help us to connect/maintain the database. so let’s download and install the robo3t from the following URL

  • https://robomongo.org/download

Setup the connection string


Next, open a project in eclipse IDE or any other IDE with which you are comfortable. Inside the resources folder, open application.properties and add the following connection string

spring.data.mongodb.uri=mongodb://localhost:27017/todo-manager-api

Here, todo-manager-api is the database name

Create an Entity class


Create a new entity class TodoDTO.java inside the package in.bushansirgur.springbootmongodb.model and add the following code

TodoDTO.java

package in.bushansirgur.springbootmongodb.model;

import java.util.Date;

import javax.validation.constraints.NotNull;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Document(collection="todos")
public class TodoDTO {

	
	@Id
	private String id;
	
	@NotNull(message="Todo cannot be null")
	private String todo;
	
	@NotNull(message="Description cannot be null")
	private String description;
	
	@NotNull(message="Completed cannot be null")
	private Boolean completed;
	
	private Date createdAt;
	
	private Date updatedAt;
}

Create a Repository interface


Create an interface TodoRepository.java inside the package in.bushansirgur.springbootmongodb.repository that extends the JpaRepository.




TodoRepository.java 

package in.bushansirgur.springbootmongodb.repository;

import java.util.Optional;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;

import in.bushansirgur.springbootmongodb.model.TodoDTO;

@Repository
public interface TodoRepository extends MongoRepository<TodoDTO, String> {
	
	@Query("{'todo': ?0}")
	Optional<TodoDTO> findByTodo(String todo);
}

Setup the configuration for validation


So we have to setup some validations for our entity class so let’s create a class ValidationConfig.java that configures the validation. Create a package in.bushansirgur.springbootmongodb.config and add the following code inside the configuration class

ValidationConfig.java

package in.bushansirgur.springbootmongodb.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

@Configuration
public class ValidationConfig {
	
	@Bean
	public ValidatingMongoEventListener validationMongoEventListener() {
		return new ValidatingMongoEventListener(validator());
	}
	
	@Bean
	public LocalValidatorFactoryBean validator() {
		return new LocalValidatorFactoryBean();
	}
}

Create a custom exception handler


We need to create a custom exception handler to catch the business exceptions, so let’s create one for our application. Create a package in.bushansirgur.springbootmongodb.exception and inside this create a class TodoCollectionException.java, and add the following code




TodoCollectionException.java

package in.bushansirgur.springbootmongodb.exception;

public class TodoCollectionException extends Exception {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public TodoCollectionException(String message) {
		super(message);
	}
	
	public static String NotFoundException(String id) {
		return "Todo with "+id+" not found!";
	}
	
	public static String TodoAlreadyExists() {
		return "Todo with given name already exists";
	}
}

Create a Service and Service implementation


Now let’s create service interface TodoService.java inside the package in.bushansirgur.springbootmongodb.service and add the following code

TodoService.java

package in.bushansirgur.springbootmongodb.service;

import java.util.List;

import in.bushansirgur.springbootmongodb.exception.TodoCollectionException;
import in.bushansirgur.springbootmongodb.model.TodoDTO;

public interface TodoService {
	
	public List<TodoDTO> getAllTodos();
	
	public TodoDTO getSingleTodo(String id) throws TodoCollectionException;
	
	public void createTodo(TodoDTO todo) throws TodoCollectionException;
	
	public void updateTodo(String id, TodoDTO todo) throws TodoCollectionException;
	
	public void deleteTodoById(String id) throws TodoCollectionException;
}

Now let’s create an implementation class TodoServiceImpl.java inside the same package and add the following code

package in.bushansirgur.springbootmongodb.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import in.bushansirgur.springbootmongodb.exception.TodoCollectionException;
import in.bushansirgur.springbootmongodb.model.TodoDTO;
import in.bushansirgur.springbootmongodb.repository.TodoRepository;

@Service
public class TodoServiceImple implements TodoService {

	@Autowired
	private TodoRepository todoRepo;
	
	@Override
	public List<TodoDTO> getAllTodos() {
		List<TodoDTO> todos = todoRepo.findAll();
		if (todos.size() > 0) {
			return todos;
		}else {
			return new ArrayList<TodoDTO>();
		}
	}

	@Override
	public TodoDTO getSingleTodo(String id) throws TodoCollectionException{
		Optional<TodoDTO> todoOptional = todoRepo.findById(id);
		if (!todoOptional.isPresent()) {
			throw new TodoCollectionException(TodoCollectionException.NotFoundException(id));
		}else {
			return todoOptional.get();
		}
	}

	@Override
	public void createTodo(TodoDTO todo) throws TodoCollectionException{
		Optional<TodoDTO> todoOptional= todoRepo.findByTodo(todo.getTodo());
        if(todoOptional.isPresent())
        {
            throw new TodoCollectionException(TodoCollectionException.TodoAlreadyExists());
        }
        else
        {
        	todo.setCreatedAt(new Date(System.currentTimeMillis()));
            todoRepo.save(todo);
        }
		
	}

	@Override
	public void updateTodo(String id, TodoDTO todo) throws TodoCollectionException{
		Optional<TodoDTO> todoWithId = todoRepo.findById(id);
        Optional<TodoDTO> todoWithSameName = todoRepo.findByTodo(todo.getTodo());
        if(todoWithId.isPresent())
        {
            if(todoWithSameName.isPresent() && !todoWithSameName.get().getId().equals(id))
            {

                throw new TodoCollectionException(TodoCollectionException.TodoAlreadyExists());
            }
            TodoDTO todoToUpdate=todoWithId.get();
            
            todoToUpdate.setTodo(todo.getTodo());
            todoToUpdate.setDescription(todo.getDescription());
            todoToUpdate.setCompleted(todo.getCompleted());
            todoToUpdate.setUpdatedAt(new Date(System.currentTimeMillis()));
            todoRepo.save(todoToUpdate);
        }
        else
        {
            throw new TodoCollectionException(TodoCollectionException.NotFoundException(id));
        }
	}

	@Override
	public void deleteTodoById(String id) throws TodoCollectionException{
		Optional<TodoDTO> todoOptional = todoRepo.findById(id);
        if(!todoOptional.isPresent())
        {
            throw new TodoCollectionException(TodoCollectionException.NotFoundException(id));
        }
        else
        {
            todoRepo.deleteById(id);
        }
		
	}
}

Create a controller and create the rest end points


Now let’s create a controller inside the package in.bushansirgur.springbootmongodb.controller and add the following code




TodoController.java

package in.bushansirgur.springbootmongodb.controller;

import java.util.List;

import javax.validation.ConstraintViolationException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import in.bushansirgur.springbootmongodb.exception.TodoCollectionException;
import in.bushansirgur.springbootmongodb.model.TodoDTO;
import in.bushansirgur.springbootmongodb.service.TodoService;

@RestController
public class TodoController {
	
	@Autowired
	private TodoService todoService;
	
	@PostMapping("/todos")
	public ResponseEntity<?> createTodo(@RequestBody TodoDTO todo) {
		try {
			todoService.createTodo(todo);
			return new ResponseEntity<TodoDTO>(todo, HttpStatus.OK);
		} catch (ConstraintViolationException e) {
			return new ResponseEntity<>(e.getMessage(), HttpStatus.UNPROCESSABLE_ENTITY);
		} catch (TodoCollectionException e) {
			return new ResponseEntity<>(e.getMessage(), HttpStatus.CONFLICT);
		}
	}
	
	@GetMapping("/todos")
	public ResponseEntity<?> getAllTodos() {
		List<TodoDTO> todos = todoService.getAllTodos();
		return new ResponseEntity<>(todos, todos.size() > 0 ? HttpStatus.OK : HttpStatus.NOT_FOUND);
	}
	
	@GetMapping("/todos/{id}")
	public ResponseEntity<?> getSingleTodo(@PathVariable("id") String id){
		try {
			return new ResponseEntity<>(todoService.getSingleTodo(id), HttpStatus.OK);
		} catch (TodoCollectionException e) {
			return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
		}
	}
	
	@DeleteMapping("/todos/{id}")
	public ResponseEntity<?> deleteById(@PathVariable("id") String id) throws TodoCollectionException{
		try{
            todoService.deleteTodoById(id);
            return new ResponseEntity<>("Successfully deleted todo with id "+id, HttpStatus.OK);
        }
        catch (TodoCollectionException e)
        {
            return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
        }	
	}
	
	@PutMapping("/todos/{id}")
    public ResponseEntity<?> updateById(@PathVariable("id") String id, @RequestBody TodoDTO todo)
    {
		try {
            todoService.updateTodo(id,todo);
            return new ResponseEntity<>("Updated movie with id "+id+"", HttpStatus.OK);
        }
        catch(ConstraintViolationException e)
        {
            return new ResponseEntity<>(e.getMessage(), HttpStatus.UNPROCESSABLE_ENTITY);
        }
        catch (TodoCollectionException e) {
            return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
        }
    }
}

Run the main class


When we create a new spring boot project it automatically creates a main class for us, inside the package in.bushansirgur.springbootmongodb with class name SpringbootmongodbApplication.java, open it and run the file

SpringbootmongodbApplication.java

package in.bushansirgur.springbootmongodb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootmongodbApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootmongodbApplication.class, args);
	}

}

 

Download the project from Github


You can clone the entire app from the following Github repository



clone the project Spring boot and mongodb REST API 

 

Watch the full video tutorial


You can watch the entire tutorial in the following link

Bushan Sirgur

Hey guys, I am Bushan Sirgur from Banglore, India. Currently, I am working as an Associate project in an IT company.

Leave a Reply