Spring Boot Crud Application Tutorial with MongoDB

Welcome to this quick tutorial on creating a spring boot crud application with MongoDB database. This tutorial assumes that you are familiar with Java web applications, spring framework, MongoDB and gradle build system. This tutorial also uses spring tool suite(STS) as the IDE. If you are not familiar with STS, check out getting started with spring boot and STS tutorial.

Spring boot makes things so easy that sometimes it might seem like magic! High productivity and concise code is achieved through spring boot  starter projects and auto configuration of components. Let us get started on our first spring boot crud application.

Step 1: Create a spring boot project from a starter project using spring tool suite. Follow the instructions in this spring boot tutorial. Delete the HomeController.java from the project if you have created it following the above tutorial.

Step 2: Install and run a MongoDB instance locally. This tutorial uses a MongoDB database for persisting the data. Download the community edition from here and extract the zip to a folder of your choice. Add the bin folder in the operating system path. Then create a folder where you want MongoDB to keep its data file. Use the following command to run MongoDB from console,

mongod --dbpath <your path to datafiles>

You can connect to the running MongoDB instance using the following command,

mongo

In the mongo console, type the following command to see databases. You should see "test" database in the list.

show dbs

Following are some of the useful commands in mongo console,

Switch to "test" database,

use test

Show tables in the current database,

show collections

Print all records in the customer collection (after the collection is created from the application),

db.customer.find()

Step 3: Replace the build.gradle with the following file. This file has two additional dependencies. The library spring-boot-starter-data-rest is used for enabling REST endpoints for data repositories and spring-boot-starter-data-mongodb is used for MongoDB connectivity. Spring boot auto configuration wires them all together and assumes that you are connecting to a local Mongo instance at the default port. No further configuration is required!

buildscript {
    ext { 
        springBootVersion = '1.5.2.RELEASE'
    }
    repositories {
        mavenCentral() 
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    } 
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

jar {
    baseName = 'demoapp'
    version = '0.0.1-SNAPSHOT'
}

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-data-rest')
    compile("org.springframework.boot:spring-boot-starter-data-mongodb")	

    testCompile('org.springframework.boot:spring-boot-starter-test')
}

Step 4: Create a Java object representation for MongoDB table. In this tutorial we will create a simple crud for customer data. Following is a Java bean representing a single customer record in the mongo customer table. Please note that you don't need to create this collection/table in mongo, it will be automatically created during the first insert.

package com.quickprogrammingtips.demoapps;

import org.springframework.data.annotation.Id;

// Java bean representation of Mongo customer table
public class Customer {
    @Id private String id;
    private String name;
    private String email;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
}

Step 5: Create a repository class for customer object. A spring repository is an interface which allows us to access our database tables. By extending our repository from MongoRepository, we are indicating that we are using a mongo collection. Annotate it using @RepositoryRestResource so that it is exposed as a REST endpoint automatically. Note that we specified the mongo collection name (collectionResourceRel) and the REST url path (path) in the annotation. Even @RepositoryRestResource is optional if you just want default collection to url path mapping!

package com.quickprogrammingtips.demoapps;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource(collectionResourceRel = "customer", path = "customer")
public interface CustomerRepository extends MongoRepository<Customer, String>{

}

The actual implementation of the above interface is automatically created by spring boot. If you need access to this repository in your classes you can inject in using the @Autowired annotation. In our example even that is not necessary since the REST controller for the repository is auto created by spring boot!

Step 6: Run the spring boot application from IDE. Right click the project and click on Run As => Spring Boot App. If all goes well, your application and its REST endpoints will be up and running on http://localhost:8080.

Step 7: Access the crud features from the following links. To POST data, you can use browser extensions such as postman or use the curl command line tool.

  • GET http://localhost:8080/customer - Queries all customers. The data is returned in json format.
  • GET http://localhost:8080/customer/<object_id> - Queries the customer corresponding to the mongo object id specified. You can find the object id from the db directly.
  • POST http://localhost:8080/customer  - Saves the customer record json specified in the post body.
  • DELETE http://localhost:8080/customer/<object_id>  - Deletes the customer record corresponding to the mongo object id specified.

For example, the following curl command creates a new customer record is database. Login to mongo console to verify that the records are inserted in the database.

curl -i -X POST -H "Content-Type:application/json" -d '{"name":"qpt","email":"quickprogrammer@gmail.com"}' localhost:8080/customer

The following curl command deletes a customer record,

curl -i -X DELETE http://localhost:8080/customer/58bba27b82127c348722df0f

Voila! Now you have a complete crud application with a few lines of code. This implementation is also suitable for building microservices using spring boot.

Customizing Spring Boot Application

Ok. All this auto configuration is cool. But what if I want to use my own configuration? For example, what if I want to connect to a remote MongoDB instance. Luckily spring boot allows us to override defaults whenever needed. Here are some examples of configuring spring boot,

How to Configure MongoDB in Spring Boot

If you want to connect to a non local mongo database instance, you can specify the configuration in the application.properties located at src/main/resources. In the following url, user:password@ is the optional login credentials for the mongodb. The last part of the url(test) indicates the name of the database.

spring.data.mongodb.uri=mongodb://user:password@192.168.1.5:27017/test

 

How to Implement a Custom Query REST Endpoint?

In the above example, what if you want search for customers with a specific email id? You can implement custom searches by adding findBy methods on the column. Check out the following updated CustomerRepository with a custom search on email column added. Such methods are automatically mapped to the /customer/search endpoint. Also note that the @Param annotation indicates the name of the http query parameter used for search.

package com.quickprogrammingtips.demoapps;
import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource(collectionResourceRel = "customer", path = "customer")
public interface CustomerRepository extends MongoRepository<Customer, String>{
    List<Customer> findByEmail(@Param("mail") String mail);
}

Invoke the following endpoint to find the list of search queries available,

http://localhost:8080/customer/search

Invoke the following endpoint to find all the customers with a specified email,

http://localhost:8080/customer/search/findByEmail?mail=quickprogrammer@gmail.com