Spring Boot CRUD Application Example with MongoDB
Tags: spring, java, mongodb, gradle
Published: 2021-01-23 17:14:00

## Introduction
In this post, I will show how we can use Spring Boot to build a simple CRUD REST application example with MongoDB. I know your first question will be what is MongoDB?

## What is MongoDB?
[MongoDB](https://betterjavacode.com/programming/fundamentals-of-a-distributed-system-design) is a NoSQL document database. In this database, records are documents that behave a lot like JSON objects. So it is mostly key-value pair.

The key advantages of using MongoDB as a database are:
* MongoDB is a schema less document database. One collection holds different documents.
* Structure of a single object is clear.
* No complex joins.
* Deep query ability.
* Easy to scale-out

Here are a few reasons why you would use MongoDB or similar NoSQL databases in enterprise applications:
* If you need faster data retrieval in JSON style
* Easy to add index on an attribute
* For Sharding purposes – Sharding is the process of storing data records across multiple machines. You will usually partition this data according to some criteria while storing across multiple machines.
* Fast in-place updates
* Easier to query

## Prerequisites

To create this sample application, you need:
* Spring Boot (version 2.4.1)
* MongoDB
* Gradle
* Java

## Spring Boot CRUD Application
As part of this post, I will be building a REST CRUD application. 

This includes:
* A book library – We will be creating a collection library in our MongoDB database.
* A library where we will be storing the books by author
* A user can call the REST API to retrieve the book by author
* A user can call the REST API to retrieve all the books from the library
* POST – /v1/mongodbapp/books – To add a book to library
* GET – /v1/mongodbapp/books – To retrieve all the books from the 
library
* GET – /v1/mongodbapp/books/id – To retrieve a specific book
* DELETE – /v1/mongodbapp/books/id – To remove a book from the library


## How to use Spring Boot CRUD with MongoDB
To get started with creating this application, we will be using gradle to handle our dependencies and build the application. Add the following dependencies in our Spring Boot application:

```
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-web'

```
Once we have these dependencies, we will be able to connect to mongo db database. But we still need to add where our database is located. We will add the required properties in our `application.properties` file as below:

```
spring.data.mongodb.host = localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=library

```
This will allow us to connect to MongoDB database running at host localhost on the port `27017` and the database schema is library.

### Define Data Model

As part of the library, we will need books. So our main data object is Book. The data model for this will include the book title, author, and ISBN. This will be as follows:

```
package com.betterjavacode.mongodbdemo.mongodbapp.models;

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



@Document(collection = "books")
public class Book
{
    @Id
    private String id;

    private String title;
    private String author;
    private String isbn;

    public Book()
    {

    }

    public Book(String title, String author, String isbn)
    {
        this.title = title;
        this.author = author;
        this.isbn = isbn;
    }

    public String getId ()
    {
        return id;
    }

    public void setId (String id)
    {
        this.id = id;
    }

    public String getTitle ()
    {
        return title;
    }

    public void setTitle (String title)
    {
        this.title = title;
    }

    public String getAuthor ()
    {
        return author;
    }

    public void setAuthor (String author)
    {
        this.author = author;
    }

    public String getIsbn ()
    {
        return isbn;
    }

    public void setIsbn (String isbn)
    {
        this.isbn = isbn;
    }
}

```

Since we are using MongoDB, `@Document` annotation overrides the collection books.

### Add Repository Interface

We will need a repository interface to fetch, save or delete our book object.  In `repositories` package, we will add `BookRepository` interface

```
package com.betterjavacode.mongodbdemo.mongodbapp.repositories;

import com.betterjavacode.mongodbdemo.mongodbapp.models.Book;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;

public interface BookRepository extends MongoRepository<Book, String>
{
    List findByTitleContaining(String title);
    List findByAuthor(String name);
}

```

This repository has two methods to fetch list of books by a title or by author name.

### Add Spring REST API Controller

Now to make our application REST CRUD, we will add a REST controller. This controller will contain `POST`, `PUT`, `GET` and `DELETE` APIs.

```
package com.betterjavacode.mongodbdemo.mongodbapp.controller;

import com.betterjavacode.mongodbdemo.mongodbapp.models.Book;
import com.betterjavacode.mongodbdemo.mongodbapp.repositories.BookRepository;
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.Optional;

@CrossOrigin("http://localhost:8080")
@RestController
@RequestMapping("/v1/mongodbapp")
public class BookController
{
    @Autowired
    BookRepository bookRepository;

    @GetMapping("/books")
    public ResponseEntity<List> getAllBooks(@RequestParam(required = false) String bookTitle)
    {
        try
        {
            List listOfBooks = new ArrayList<>();
            if(bookTitle == null || bookTitle.isEmpty())
            {
                bookRepository.findAll().forEach(listOfBooks::add);
            }
            else
            {
                bookRepository.findByTitleContaining(bookTitle).forEach(listOfBooks::add);
            }

            if(listOfBooks.isEmpty())
            {
                return new ResponseEntity<>(HttpStatus.NO_CONTENT);
            }

            return new ResponseEntity<>(listOfBooks, HttpStatus.OK);
        }
        catch (Exception e)
        {
            return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @GetMapping("/books/{id}")
    public ResponseEntity getBookById(@PathVariable("id") String id)
    {
        try
        {
            Optional bookOptional = bookRepository.findById(id);

            return new ResponseEntity<>(bookOptional.get(), HttpStatus.OK);
        }
        catch (Exception e)
        {
            return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @PostMapping("/books")
    public ResponseEntity addABookToLibrary(@RequestBody Book book)
    {
        try
        {
            Book createdBook = bookRepository.save(new Book(book.getTitle(), book.getAuthor(),
                    book.getIsbn()));
            return new ResponseEntity<>(createdBook, HttpStatus.CREATED);
        }
        catch (Exception e)
        {
            return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @PutMapping("/books/{id}")
    public ResponseEntity updateABook(@PathVariable("id") String id, @RequestBody Book book)
    {
        Optional bookOptional = bookRepository.findById(id);

        if(bookOptional.isPresent())
        {
            Book updatedBook = bookOptional.get();
            updatedBook.setTitle(book.getTitle());
            updatedBook.setAuthor(book.getAuthor());
            updatedBook.setIsbn(book.getIsbn());
            return new ResponseEntity<>(bookRepository.save(updatedBook), HttpStatus.OK);
        }
        else
        {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

    @DeleteMapping("/books/{id}")
    public ResponseEntity deleteABook(@PathVariable("id") String id)
    {
        try
        {
            bookRepository.deleteById(id);
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        }
        catch (Exception e)
        {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}


```
`BookController` is our REST Controller class. It includes

    * @RestController – to mark this as a REST controller.
    * @CrossOrigin – This annotation allows cross-origin resource sharing (CORS). This will add CORS access control headers in the REST response. These headers are necessary because it allows servers to specify not only who can access the resources, but how they can be accessed.
    * We have added different methods – addABookToLibrary adds the book to database, getAllBooks retrieves the book from database.

## The Complete Demo

Now we have added our REST controller, repository methods, we will build and run this application. As part of the demo, I will use POSTMAN to access APIs.

You can build the application from command line or from the code editor you are using. I prefer command line, so I already built the application. Once built, you can run the program as follows:

`java -jar mongodbapp-0.0.1-SNAPSHOT.jar.`

Let’s use POSTMAN to add books to our library.

![Spring Boot CRUD Application MongoDB - Create](https://dev-to-uploads.s3.amazonaws.com/i/xaqlo443iw6saxql2za9.JPG)

As shown above, we added a book and the response shows the added book in the database.

The following API is a GET API to get all the books from the database.

![Spring Boot CRUD Application MongoDB - Get All](https://dev-to-uploads.s3.amazonaws.com/i/dmwiqh6oocu7qlqwqegx.JPG)

Now to show delete the book from library, we will use DELETE API.

![Spring Boot CRUD Application MongoDB - Delete](https://dev-to-uploads.s3.amazonaws.com/i/onbivgvo9778inz8gyx7.JPG)

The code for this sample application is available in my [github repository](https://github.com/yogsma/mongodbapp).

If you want to see this data in MongoDB database, you can access MongoDB compass tool and access the collection books in library database.

![Mongo DB](https://dev-to-uploads.s3.amazonaws.com/i/em8gzv2vzujzcfhkfbbn.JPG)

## Conclusion

In this post, I showed how to use Spring Boot to create REST API while using MongoDB database. The approach we used is very similar to what we have while using a regular SQL database. There are some changes that we have to add while using NoSQL database. If you find this post useful or have any questions that I can help you with, you can subscribe to my blog [here](https://betterjavacode.com/subscribe).