spring

Spring Data MongoDB REST Example

In this tutorial, I will show you how to develop a RESTful web application by using Spring and MongoDB without implementing boring uniform controllers.

1. Introduction

When it comes to RESTful application, we need an api that mainly handles CRUD operations. Let me give you example to clearify what I mean by sentence above. Let say that, you have a REST endpoint /products that allows you to perform product related operations like Product Create, Product Update, Product View, Product Delete, or Product Search. The minimum code requirements for designing such an endpoint is nearly same for every resources like below:

  • Design your domain model (Product)
  • Implement Repository
  • Implement Controller
Quick Tip
You will see the term resource in this article frequently. It is one of the main components of the RESTful design and you can refer here to learn more about what a resource is.

By using above components, you can handle requests with controllers, validate and convert request to Entity, and finaly perform CRUD operation by using Service that use DAO classes for each entity. In this situation, you need to code 4 endpoint for each resource(Product is a resource here). Let say that you have 10 resources in your project like User, Comment, History, etc.. You will have 10 x 4 endpoint needs to be implemented. Those endpoints are mainly same for all resources. What if we do not need to implement those CRUD enpoints for each resources? We will use Spring Data Rest project for lead to implement RESTful services by implementing only Repository and Domain Model.

2. Requirements

In this project, we will need following requirements;

  • Maven 3.x
  • Spring Boot 1.2.5
  • Valid MongoDB database

I have prefered Spring Boot for fast web development with Spring. If you have never heard about Spring Boot, you can have a look at here. I have specified the version according to current time, but you don’t need to do anything with versions, I will provide pom.xml for dependencies. You can see example pom.xml below;

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>

    <groupId>huseyinbabal.net</groupId>
    <artifactId>spring-mongodb-data-rest</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.5.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
    </dependencies>
	
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

In above dependecy xml, we have only 2 dependecies for REST and MongoDB related operations. spring-boot-starter-parent is for minimum dependency for Spring Boot to allow us to develop web projects. spring-boot-maven-plugin is for running Spring Boot projects by using maven. Let see all of them in action with a demo application.

3. Domain Model

We will develop a RESTful service for Product related operations. Let’s create a domain object for Product.

Product.java

package main.java.springmongodbdatarest;

import org.springframework.data.annotation.Id;

public class Product {
	
	@Id
	private String id;
	
	private String name;
	private String title;
	private String description;
	private String imageUrl;
	private double price;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public String getImageUrl() {
		return imageUrl;
	}
	public void setImageUrl(String imageUrl) {
		this.imageUrl = imageUrl;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}	
}

This object will be used to persist product data to MongoDB and also when we read a product data from MongoDB, it will be authomatically casted to this object. We will not do anything about persistence, Spring will handle all of the MongoDB operations. And @Id annotation in product model is for generating automatic id for MongoDB. Let’s continue with Repository.

4. Repository

We need a repository interface to make MongoDB related operations by using Product model. We can use ProductRepository for our case. You can see an example repository interface below.

ProductRepository.java

package main.java.springmongodbdatarest;

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

@RepositoryRestResource(collectionResourceRel = "products", path = "products")
public interface ProductRepository extends MongoRepository<Product, String> {

}

As you can see, this simple interface will handle all of your db related operations, and it will also implement REST endpoints with some annotations. But, how?

We have spring-data-rest dependency and this will make an implementation of above interface at runtime. By using @RepositoryRestResource, it will create an endpoint /products. collectionResourceRel is for MongoDB collection name, that means, when you create a product, it will be persisted to MongoDB database inside products collection as we stated with collectionResourceRel. path is for rest endpoint name for the product model. ProductRepository interface extends MongoRepository to inhert some DB related operations, so Spring will automatically use save(), find(), etc.. kind methods for your model. Lastly, we have provided Product and String to MongoRepository and this means that this repository will make db operations through Product model, and data type of primary id field of this model is String

5. MongoDB

In order to run your project successfully, you need valid MongoDB database. Spring Boot uses localhost:27017/test by default. If you want to override database properties, create application.properties in resources folder and put following content in it.

MongoDB URL in property file

spring.data.mongodb.uri=mongodb://localhost:27017/test

You can also see example in sample project.

6. Boot Up

In order to make this REST service up, we will use following bootstrap class;

Application.java

package main.java.springmongodbdatarest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

We are saying that, this is an SpringBootApplication and go get the dependencies and run required components. You can put all 3 classes inside same package.

In order to run project, go to project folder and run mvn spring-boot:run. This will run project and you will be able to access REST service endpoints on 8080 port.

7. Let See It In Action!

When you make a request to application root(In my case: http://localhost:8080) you will see the available endpoints for all resources like below

Sample REST Response

{
    "_links": {
        "products": {
            "href": "http://localhost:8080/products{?page,size,sort}",
            "templated": true
        },
        "profile": {
            "href": "http://localhost:8080/alps"
        }
    }
}

As you can see, there is only one resource products and you can see list of products by going url in the href. Note that, you can manipulate product results by using page, size, and sort. Let’s add one product to the database.

Product model has 5 fields, and we will post that details in the request payload. Before proceeding data creation, HTTP methods has following roles in RESTful services.

  • POST: Create
  • PUT: Total update
  • PATCH: Partial update
  • DELETE: Delete
  • GET: View

So, If we want to create a record, we can make a POST request to http://localhost:8080/products with product payload. You can see example below:

Request Payload for Product Creation

{
    "name": "Glass",
    "title": "Beatiful Glass",
    "descriptions": "This is one of the greatest glass",
    "imageUrl": "http://img.com",
    "price": "4

quot;
}
When you make this request, you will get a response with status code 201(Created). We have a product data now, and you can list products now by going url http://localhost:8080/products. The response will be like below

Product Detail Response

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/products{?page,size,sort}",
      "templated" : true
    }
  },
  "_embedded" : {
    "products" : [ {
      "name" : "Glass",
      "title" : "Beatiful Glass",
      "description" : null,
      "imageUrl" : "http://img.com",
      "price" : 4.0,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/products/55cc79774568615d83f718be"
        }
      }
    } ]
  },
  "page" : {
    "size" : 20,
    "totalElements" : 1,
    "totalPages" : 1,
    "number" : 0
  }
}

As you can see, there is a url for each resource to make resource specific operations. For example, you can delete resource by performing DELETE request to http://localhost:8080/products/55cc79774568615d83f718be, you will get 204(No content). The record deleted and returned no content.

8. Summary

RESTful API needs to be designed very carefully. Spring Data Rest project handles RESTful API concepts very good. In this article, I have tried to explain you how to use Spring Data Rest within your projects. Hope this is helpful for you. See you in next article!

Download
You can download the full source code of the project here: SpringMongoDBDataRestExample

Huseyin Babal

Huseyin Babal has deep experience in Full Stack Development since 2007. He is mainly developing applications with JAVA, Spring, PHP, NodeJS, AngularJS. He is also interested in DevOps Engineering since 2013 and using AWS, Heroku for Cloud deployment and playing with Docker and Consul for implementing infinite scalable systems. He likes to share his experience in public conferences and perform advanced workshops about Full Stack Development and Devops. He is the author of NodeJS in Action course in Udemy.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button