In this tutorial, we will learn creating a REST API using Spring Boot and MongoDB. We will perform the basic database operations like Create, Read, Update and Delete. So we will create a backend application using Spring boot and we will provide a full CRUD support using MongoDB. So let’s begin..
When we are working with Spring boot and MongoDB, we cant use @GeneratedValue annotation in our entity class as it does not support. But somehow we need to use auto generated field so that we can keep track of employee records and perform the Read, Update and Delete operations. In this tutorial, we will also learn generating auto id for the each document.
Setup MongoDB Database
In order to use MongoDB i will make use of https://mlab.com/ website which provide a MongoDB database service online. So we can connect to their website and use MongoDB. Watch the below video to setup the MongoDB database in mLab.
NOTE: If you don’t want to use mLab and if you want to use MongoDB locally, you can use that as well.
Tools and Technologies Used:
- Spring Boot – 2.1.2.RELEASE
- Spring Framework – 5.1.4.RELEASE
- Spring Data – 2.1.4.RELEASE
- MongoDB – 3.8.2
- JDK – 1.8 or later
- IDE – Eclipse Oxygen
Now let’s look at the development steps,
Development Steps
- Create Spring boot application
- Update the pom.xml file
- Project structure
- Configure MongoDB in mLab
- Create model class
- Create Spring data repository
- Create controller
- Run application
- Test REST API’s using Rest client
Let’s look at the steps one by one
1. Create Spring boot application
There are many ways to create Spring boot application, you can use any one of the way to create spring boot application and open it in Eclipse
2. Update the pom.xml file
We will add two main dependencies spring-boot-starter-data-mongodb
and spring-boot-starter-web
in pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>in.bushansirgur</groupId> <artifactId>spring-boot-mongodb-rest-api</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-mongodb-rest-api</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <start-class>in.bushansirgur.restapi.SpringBootMongodbRestApiApplication</start-class> </properties> <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.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3. Project structure
Below is the Spring boot project structure for your reference..
4. Configure MongoDB in mLab
Spring boot tries to connect mongoDB by reading the pom.xml
dependency spring-boot-starter-data-mongodb
which we have added. All we need to do is add the database url in the application.properties
file.
#spring.data.mongodb.uri=mongodb://<username>:<password>@ds021694.mlab.com:21694/b2tech spring.data.mongodb.uri=mongodb://admin:[email protected]:21694/b2tech
As per my mLab configuration mongodb running on the port 21694
, username is admin
and password is admin123
.
NOTE: Make sure to use your configuration, do not use mine.
If you have installed mongodb locally then add this,
spring.data.mongodb.uri=mongodb://localhost:27017/employees
and make sure to create employees
database using the following command:
use employees
5. Create model classes
We are going to create two model classes DatabaseSequence
which creates a auto generated value for the id
column.
package in.bushansirgur.restapi.model; import org.springframework.data.annotation.Id; public class DatabaseSequence { @Id private String id; private long seq; public String getId() { return id; } public void setId(String id) { this.id = id; } public long getSeq() { return seq; } public void setSeq(long seq) { this.seq = seq; } @Override public String toString() { return "DatabaseSequence [id=" + id + ", seq=" + seq + "]"; } }
Now, let’s create EmployeeModel
class to store the employee object
package in.bushansirgur.restapi.model; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document(collection = "employees") public class EmployeeModel { public static final String SEQUENCE_NAME = "employees_sequence"; @Id private Long id; private String name; private String gender; private String dob; private String country; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getDob() { return dob; } public void setDob(String dob) { this.dob = dob; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } @Override public String toString() { return "EmployeeModel [id=" + id + ", name=" + name + ", gender=" + gender + ", dob=" + dob + ", country=" + country + "]"; } }
6. Create spring data repository
Next, we need to create repository EmployeeDAO
to access the data from database
package in.bushansirgur.restapi.dao; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; import in.bushansirgur.restapi.model.EmployeeModel; @Repository public interface EmployeeDAO extends MongoRepository<EmployeeModel, Long> { }
Now let’s create SequenceGeneratorService
to create the auto generated value for id
property
package in.bushansirgur.restapi.service; import java.util.Objects; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Service; import in.bushansirgur.restapi.model.DatabaseSequence; import static org.springframework.data.mongodb.core.FindAndModifyOptions.options; import static org.springframework.data.mongodb.core.query.Criteria.where; import static org.springframework.data.mongodb.core.query.Query.query; @Service public class SequenceGeneratorService { @Autowired private MongoOperations mongo; public long generateSequence(String seqName) { DatabaseSequence counter = mongo.findAndModify(query(where("_id").is(seqName)), new Update().inc("seq",1), options().returnNew(true).upsert(true), DatabaseSequence.class); return !Objects.isNull(counter) ? counter.getSeq() : 1; } }
7. Create controller
Next let’s create a rest end points using @GetMapping
, @PostMapping
, @PutMapping
, @DeleteMapping
. We have annotated with @RestController
to create rest end points. Also notice that we are calling generateSequence()
while creating employee record.
package in.bushansirgur.restapi.controller; import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; 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.RequestMapping; import org.springframework.web.bind.annotation.RestController; import in.bushansirgur.restapi.dao.EmployeeDAO; import in.bushansirgur.restapi.model.EmployeeModel; import in.bushansirgur.restapi.service.SequenceGeneratorService; @RestController @RequestMapping("/api") public class EmployeeController { @Autowired EmployeeDAO employeeDAO; @Autowired SequenceGeneratorService seqGeneratorService; @PostMapping("/create") public EmployeeModel create(@RequestBody EmployeeModel newEmployeeObject) { newEmployeeObject.setId(seqGeneratorService.generateSequence(EmployeeModel.SEQUENCE_NAME)); return employeeDAO.save(newEmployeeObject); } @GetMapping("/read") public List<EmployeeModel> read(){ return employeeDAO.findAll(); } @GetMapping("/read/{id}") public EmployeeModel read(@PathVariable Long id) { Optional<EmployeeModel> employeeObj = employeeDAO.findById(id); if(employeeObj.isPresent()) { return employeeObj.get(); }else { throw new RuntimeException("Employee not found with id "+id); } } @PutMapping("/update") public EmployeeModel update(@RequestBody EmployeeModel modifiedEmployeeObject) { return employeeDAO.save(modifiedEmployeeObject); } @DeleteMapping("/delete/{id}") public String delete(@PathVariable Long id) { Optional<EmployeeModel> employeeObj = employeeDAO.findById(id); if(employeeObj.isPresent()) { employeeDAO.delete(employeeObj.get()); return "Employee deleted with id "+id; }else { throw new RuntimeException("Employee not found for id "+id); } } }
8. Run the application
Since this is a Spring boot application, you will get a main method SpringBootMongodbRestApiApplication
. You can run this application just like normal java class.
package in.bushansirgur.restapi; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootMongodbRestApiApplication { public static void main(String[] args) { SpringApplication.run(SpringBootMongodbRestApiApplication.class, args); } }
9. Test app using REST client
create a employee record
read all the employees
read a single employee
update the employee record
delete a employee record