Here, we will learn a step-by-step process for CRUD operations on MongoDB using Spring Boot.
create spring boot application using https://start.spring.io/ . select the type of project either Maven/Gradle (here we are using maven), select the dependencies like spring-boot-starter-data-mongodb, spring-boot-starter-web, lombok
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
application.yaml
Add the configuration for MongoDB properties such as host, port info, and database info. By default, the springboot application will run on port 8080; if you want to run the application on a different port, then we have to change the server port, like below.
spring:
data:
mongodb:
host: localhost
port: 27017
database: blogDb
server:
port: 8081
create Model class Blog.java
@Document annotation is used to map the class to mongo document ( i.e. Java class = Mongo document)
package com.stackbyt.springboot.mongo.model;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document("blog")
@Data
public class Blog {
@Id
private String id;
private String title;
private String url;
}
BlogRepository.java
MongoRepository will provide basic operations that we don’t need to implement separately.
@Repository
public interface BlogRepository extends MongoRepository<Blog,String> {
}
BlogService.java
package com.stackbyt.springboot.mongo.service;
import com.stackbyt.springboot.mongo.model.Blog;
public interface BlogService {
public Blog createBlog(Blog blog);
public Blog getBlog(String id);
public Blog updateBlog(Blog blog);
public void deleteBlog(String id);
}
BlogServiceImpl.java
This class will implement the functionality for createBlog, updateBlog, deleteBlog and getblog
package com.stackbyt.springboot.mongo.service;
import com.stackbyt.springboot.mongo.exception.BlogNotFoundException;
import com.stackbyt.springboot.mongo.model.Blog;
import com.stackbyt.springboot.mongo.repository.BlogRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class BlogServiceImpl implements BlogService {
private final BlogRepository blogRepository;
@Override
public Blog createBlog(Blog blog) {
return blogRepository.save(blog);
}
@Override
public Blog getBlog(String id) {
return blogRepository.findById(id).
orElseThrow(() -> new BlogNotFoundException("Blog not found with id : " + id));
}
@Override
public Blog updateBlog(Blog blog) {
Blog existingBlog = blogRepository.findById(blog.getId())
.orElseThrow(() -> new BlogNotFoundException("invalid id : " + blog.getId()));
existingBlog.setTitle(blog.getTitle());
existingBlog.setUrl(blog.getUrl());
return blogRepository.save(existingBlog);
}
@Override
public void deleteBlog(String id) {
blogRepository.deleteById(id);
}
}
BlogController.java
This class will be used to define the API’s such as create, update, delete, getBlog
package com.stackbyt.springboot.mongo.controller;
import com.stackbyt.springboot.mongo.model.Blog;
import com.stackbyt.springboot.mongo.service.BlogService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/blog")
@RequiredArgsConstructor
public class BlogController {
private final BlogService blogService;
@PostMapping("/create")
@ResponseStatus(HttpStatus.CREATED)
public Blog createBlog(@RequestBody Blog blog) {
return blogService.createBlog(blog);
}
@GetMapping("/{id}")
public ResponseEntity<Blog> getBlog(@PathVariable String id) {
return ResponseEntity.ok(blogService.getBlog(id));
}
@PutMapping
public Blog updateBlog(@RequestBody Blog blog) {
return blogService.updateBlog(blog);
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteBlog(@PathVariable String id) {
blogService.deleteBlog(id);
}
}
BlogNotFoundException.java
This is custom exception we are using to throw BlogNotFoundException if there is no Blog found for specified id
package com.stackbyt.springboot.mongo.exception;
public class BlogNotFoundException extends RuntimeException {
private String message;
public BlogNotFoundException(String message) {
super(message);
}
}
GlobalExceptionHandler.java
We will use the following class to handle exceptions globally. Write a class annotate with @RestControllerAdvice. Create methods with names prefixed by ‘handle’ (e.g., handleBlogNotFoundException) and specify the exception type as a parameter. Annotate these methods with @ExceptionHandler and specify the exception types you want to handle.
package com.stackbyt.springboot.mongo.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.time.LocalDateTime;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BlogNotFoundException.class)
public ResponseEntity<ErrorResponse> handleBogNotFoundException(BlogNotFoundException ex){
ErrorResponse errorResponse = new ErrorResponse(ex.getMessage(), LocalDateTime.now());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse);
}
}
ErrorResponse.java
to represent the error response in standard format we will use this class
package com.stackbyt.springboot.mongo.exception;
import lombok.*;
import java.time.LocalDateTime;
@AllArgsConstructor
@NoArgsConstructor
@Getter
public class ErrorResponse {
private String message;
private LocalDateTime timestamp;
}