Spring boot application with Mongo

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

Leave a Comment