In this Post, we’re gonna build a Spring Boot + MongoDB CRUD Rest API example. This project is the same as the previous spring boot + mysql rest api project the only difference is the database connection to the mongoDB. You’ll Know:
- Run MongoDB using docker compose.
- How to configure Spring Data, to work with Mongo Database
- Build a REST API — from Scratch
Before starting I made the steps in making spring boot crud as follows:
- Install Mongo DB using docker compose
- Initiate the spring boot project
- Add the required jar / dependencies to the spring boot project
- Configuration for Spring Datasource
- Create data model
- Create repository
- Create service
- Create controller
- Testing CRUD Rest API
We will build a Spring Boot + Mongo DB + Rest CRUD Rest API for a Book application in that:
- In this project we will create a library system by just creating a simple table, namely book.
- Each Book has id, title, edition, author, publisher,copies.
- Apis help to create, retrieve, retrieve detail, update, delete Book.
These are APIs that we need to provide:
Methods | Urls | Actions |
---|---|---|
POST | /api/book/add/ | Create new Book |
GET | /api/book | Retrieve all Book |
GET | /api/book/:id | Retrieve detail Book by :id |
PUT | /api/book/:id | Update Book by :id |
DELETE | /api/book/:id | Delete Book by :id |
Technology
- Java 11
- Spring Boot (with Spring Web MVC, Spring Data JPA)
- MongoDB
- Maven
- Docker
1.Install MYSQL using docker compose
Before configuring mongodb and mongoclient with docker compose you have to install docker and docker compose first. If it is installed, we can start mongodb and mongoclient configuration with docker compose.
version: "3.3"
services:
# create mongodb docker
mongodb:
image: mongo:latest
container_name: mongodb
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: rootpassword
ports:
- 27017:27017
volumes:
- .dbmongodb:/var/lib/lib/mongodb
networks:
- mongodb_net
# create mongoclient docker
mongoclient:
image: mongoclient/mongoclient:latest
container_name: mongoclient
hostname: mongoclient
depends_on:
- mongodb
networks:
- mongodb_net
ports:
- 3300:3000
networks:
mongodb_net:
driver: bridge
And run docker in background just type on terminal
docker-compose up -d
2.Initiate the spring boot project
To Create spring boot project, Open the Spring initializr https://start.spring.io.
3.Add the required jar / dependencies to the spring boot project
Add Dependencies for Spring Boot and MonogDB in pom.xml
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
4.Configuration for Spring Datasource & JPA properties
Add Configuration for Spring Datasource and Spring JPA properties in application.properties
spring.data.mongodb.uri=mongodb://root:rootpassword@localhost:27017/test_db
server.name=springboot-mongodb-crud
server.port=8888
server.servlet.context-path=/api
5.Create data model
model/Book.java
Book class corresponds to entity and table Book.
package com.lemoncode21.springbootmongodbcrud.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.UUID;
@Document(collection = "book")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Book {
@Id
private String id;
private String title;
private String edition;
private String publisher;
private Integer copies;
}
6.Create repository
repository/BookRepository.java
BookRepository is an interface extends MongoRepository, will be autowired in BookServiceImpl for implementing repository methods and custom finder methods.
package com.lemoncode21.springbootmongodbcrud.repository;
import com.lemoncode21.springbootmongodbcrud.model.Book;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface BookRepository extends MongoRepository<Book,String> {
}
7.Create service
service/BookService.java
BookService
package com.lemoncode21.springbootmongodbcrud.service;
import com.lemoncode21.springbootmongodbcrud.model.Book;
import java.util.List;
import java.util.Optional;
public interface BookService{
List<Book> retrieve();
Optional<Book> retrieveDetail(String id);
void save(Book book);
void update(Book book,String id);
void delete(String id);
}
service/Implementation/BookServiceImplementation.java
Implementation
package com.lemoncode21.springbootmongodbcrud.service.Implementation;
import com.lemoncode21.springbootmongodbcrud.model.Book;
import com.lemoncode21.springbootmongodbcrud.repository.BookRepository;
import com.lemoncode21.springbootmongodbcrud.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@Service
public class BookServiceImplementation implements BookService {
@Autowired
BookRepository bookRepository;
@Override
public List<Book> retrieve() {
return this.bookRepository.findAll();
}
@Override
public Optional<Book> retrieveDetail(String id) {
return this.bookRepository.findById(id);
}
@Override
public void save(Book book) {
book.setId(String.valueOf(UUID.randomUUID()));
this.bookRepository.save(book);
}
@Override
public void update(Book book,String id) {
Optional<Book> bookData = this.bookRepository.findById(id);
if(bookData.isEmpty()){
System.out.print("Book id not found");
}
bookData.get().setPublisher(book.getPublisher());
bookData.get().setTitle(book.getTitle());
bookData.get().setCopies(book.getCopies());
bookData.get().setEdition(book.getEdition());
this.bookRepository.save(bookData.get());
}
@Override
public void delete(String id) {
this.bookRepository.deleteById(id);
}
}
8. Create controller
BookController is a REST Controller which has request mapping methods for RESTful requests such as: getAll, getDetail, create, update, delete Book. Before build controller, I Add ResponseHandler class for handler response controller.
response/ResponseHandler.java
package com.lemoncode21.springbootmongodbcrud.response;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class ResponseHandler<T> {
@JsonProperty("status")
private String status;
@JsonProperty("message")
private String message;
@JsonProperty("data")
private T data;
public ResponseHandler(String status, String message) {
this.status = status;
this.message = message;
}
}
controller/BookController.java
package com.lemoncode21.springbootmongodbcrud.controller;
import com.lemoncode21.springbootmongodbcrud.model.Book;
import com.lemoncode21.springbootmongodbcrud.response.ResponseHandler;
import com.lemoncode21.springbootmongodbcrud.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@RestController
@RequestMapping("/book")
public class BookController {
@Autowired
BookService bookService;
@PostMapping("/add")
public ResponseHandler add(@RequestBody Book book){
try {
this.bookService.save(book);
return new ResponseHandler(HttpStatus.OK.toString(),"Success saved data!");
}catch (Exception e){
return new ResponseHandler(HttpStatus.MULTI_STATUS.toString(),e.getMessage());
}
}
@GetMapping
public ResponseHandler getAll(){
try {
List<Book> bookList = this.bookService.retrieve();
return new ResponseHandler(HttpStatus.OK.toString(),"Success retrieve data!",bookList);
}catch (Exception e){
return new ResponseHandler(HttpStatus.MULTI_STATUS.toString(),e.getMessage());
}
}
@GetMapping(value = "/{id}")
public ResponseHandler getDetail(@PathVariable("id")String id){
try {
Optional<Book> book = this.bookService.retrieveDetail(id);
return new ResponseHandler(HttpStatus.OK.toString(),"Success retrieve detail data!",book);
}catch (Exception e){
return new ResponseHandler(HttpStatus.MULTI_STATUS.toString(),e.getMessage());
}
}
@PutMapping(value = "/{id}")
public ResponseHandler update(@PathVariable("id")String id,@RequestBody Book book){
try {
this.bookService.update(book,id);
return new ResponseHandler(HttpStatus.OK.toString(),"Success update data!");
}catch (Exception e){
return new ResponseHandler(HttpStatus.MULTI_STATUS.toString(),e.getMessage());
}
}
@DeleteMapping(value = "/{id}")
public ResponseHandler delete(@PathVariable("id")String id){
try {
this.bookService.delete(id);
return new ResponseHandler(HttpStatus.OK.toString(),"Success delete data!");
}catch (Exception e){
return new ResponseHandler(HttpStatus.MULTI_STATUS.toString(),e.getMessage());
}
}
}
9.Testing CRUD Rest API
Time to test CRUD Rest API
Add Book
Retrieve All Book
Retrieve By Id Book
Update Book
Delete Book
Check code on here: https://github.com/lemoncode21/springboot-mongodb-crud.git