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.
Table of Contents
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-apiHere, 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
