How-tos

Getting started with Microservices using Spring Boot and Cloudant

Share this post:

IBM Architecture Center As part of developing cloud-native business applications, the microservices architecture has gained popularity because it simplifies the delivery of independently packaged and deployed application units as part of a larger application. By breaking down large monolithic applications into components of a microservices-based application, teams can work more independently. Additionally, thanks to devops continuous integration/continuous delivery tools, new application functionality can be delivered as its completed in an automated, replicable fashion.

In this brief how-to, you’ll learn how to create a simple microservice that manages product reviews in a Cloudant NoSQL database. The example code is written in Java and leverages the Spring Boot framework. It provides basic operations of saving and querying social review comments in the Cloudant database hosted on IBM Cloud platform.

This small sample is a modified excerpt of a larger, more complex microservices-based retail web and mobile application that is one of the IBM Cloud Architecture Center reference implementations depicted below:


Review microservice described in this post is highlighted above (in context of larger reference architecture implementation)

In the next installment of this series, I’ll walk you through how to package this Spring Boot application as a Docker container and deploy to a IBM Cloud container service.

Get development tools, provision service, get code

There several ways to access a Cloudant database in a Spring Boot application (actually Java app) such as java-cloudant, ektorp, jcouchdb etc. You can see all these libraries here. The Cloudant labs team have also released a Cloudant Spring Boot Starter which extends the java-cloudant library to provide Spring bean auto-configuration. It gives all the power of the java-cloudant library and is well integrated with Spring Boot, so this is what is used in this example.

Step 1: Download and install development tools

To complete this tutorial, you will need the following:

Once you’ve installed the above tools, begin by cloning the sample application from GitHub to your local environment:

git clone https://github.com/gangchen03/refarch-cloudnative-micro-socialreview.git

Step 2: Provision a Cloudant NoSQL DB in IBM Cloud

To provision the Cloudant service, you must have a IBM Cloud account. Login to your IBM Cloud account or register for a new account (it’s free).

To create the Cloudant service, go to the catalog: console.ng.bluemix.net/catalog/services/cloudant-nosql-db (remember to login to your IBM Cloud account). Give your Cloudant service a name like refarch-cloudantdb (select the Rename Service choice under the ACTIONS dropdown in the list of services).

For testing, you can select the “Lite” plan, then click “Create”. Once created, open the credentials tab and note your Cloudant Service credentials, for example:

{
 'username': 'xxxx-yyyy-bluemix',
 'password': 'zzzzz',
 'host': 'xxxx-yyyy-bluemix.cloudant.com',
 'port': 443,
 'url': 'https://xxxx-yyyy-bluemix:zzzzz@xxxx-yyyy-bluemix.cloudant.com'
}

Clicking the “Launch” button will open the Cloudant management console. It’s empty now.

Step 3: Build the sample application with Gradle

Now, you can work on the application. Spring Boot application can be built with either Gradle or Maven. For this how-to, the instructions are for Gradle.

Navigate into the GitHub repository root folder refarch-cloudnative-micro-socialreview; you should find the build.gradle file in that folder. It defines the library dependencies and basic build configuration such as built output. The app uses the following dependencies:

    compile("org.springframework.boot:spring-boot-starter-web:1.4.0.RELEASE") {
        exclude module: "spring-boot-starter-tomcat"
    }
    compile("org.springframework.boot:spring-boot-starter-jetty:1.4.0.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-actuator:1.4.0.RELEASE")
    compile group: 'com.cloudant', name: 'cloudant-spring-boot-starter', version: '0.0.2'
    compile("junit:junit")
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '1.4.0.RELEASE'

Notice the dependency cloudant-spring-boot-starter; it will assure that the Cloudant Spring Boot Starter will be downloaded and added to the project when you build it. When you run the Gradle build later, all the dependencies will be downloaded when it is first run.

Code walkthrough

With Spring Boot, building cloud-native microservices app is pretty easy and straightforward. Let’s take a look at the code. Under the root directory, most of the files and folders are build-related. The application code is managed under the src folder. I’ll review these four classes:

  • socialreview.cloudant.Application – bootstrap and server
  • socialreview.cloudant.Review – entity representation of a review in the database
  • socialreview.cloudant.ReviewRestController – microservice REST API for reviews
  • socialreview.cloudant.ReviewRestControllerTest – sniff test of microservice REST API for reviews

Code review: src/main/java/socialreview/cloudant/Application.java

This is the bootstrap class that loads the web application and starts an embedded server.

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        System.out.println("SocialReview Spring Boot Microservice is ready");
    }
}

The @SpringBootApplication is a convenience annotation that loads useful Spring components such as the @Configuration, @ComponentScan and @EnableAutoConfiguration. It also adds the Spring webmvc to the classpath and activates the DispatcherServlet to start handling request.

The main function invokes SpringApplication.run to bootstrap the application.

Code review: src/main/java/socialreview/cloudant/Review.java

This is an entity class that maps to the document saved in Cloudant NoSQL database. Spring Boot framework will automatically serialize the entity object with the response from the Cloudant database as well as convert it to JSON when sending the request back for the REST request.

public class Review {

    private String _rev;
    private String _id;
    private String comment;
    private int itemId;
    private int rating;
    private String reviewer_email;
    private String reviewer_name;
    private String review_date;

    public Review(){}

    public Review(boolean isStub) {
        this.comment = "It works";
        this.itemId = 13401;
        this.rating = 5;
        this.reviewer_email = "gc@ibm.com";
        this.reviewer_name = "Gang Chen";
        this.review_date = "08/18/2016";
    }

Code review: src/main/java/socialreview/cloudant/ReviewRestController.java

This is the main class that exposes the REST API and interacts with the Cloudant database to perform save and query operations.

@RestController
@RequestMapping("/review")
public class ReviewRestController {

    @Autowired
    private Database db;

The @RestController tells the Spring MVC to handle web requests with the root web context root as review.

When the Cloudant Spring Boot Starter is added as a dependency it is automatically hooked into the Spring application configuration. Using properties provided in the application’s property source the starter configures a Cloudant database bean that can be injected via dependency injection by specifying the @Autowired annotation.

// Create a new review
@RequestMapping(method = RequestMethod.POST, consumes = "application/json")
public @ResponseBody String saveReview(@RequestBody Review review) {
    System.out.println("Save Review " + review);
    Response r = null;
    if (review != null) {
        r = db.post(review);
    }
    return r.getId();
}

This code saves/persists a review comment document into the Cloudant database. It is a POST request. The Cloudant Java client makes the persistent very simple with a single API call, db.post(review), shown above. On the other hand, the GET (query) function is a little bit more complex.

// Query reviews for all documents or by ItemId
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody List getAll(@RequestParam(required=false) Integer itemId) {
    // Get all documents from socialreviewdb
    List allDocs = null;
    try {
        if (itemId == null) {
            allDocs = db.getAllDocsRequestBuilder().includeDocs(true).build().getResponse()
                        .getDocsAs(Review.class);
        } else {
            // create Index
            // Create a design doc named designdoc
            // A view named querybyitemIdView
            // and an index named itemId
	    db.createIndex("querybyitemIdView","designdoc","json",
	        new IndexField[]{new IndexField("itemId",SortOrder.asc)});
            System.out.println("Successfully created index");
            allDocs = db.findByIndex("{\"itemId\" : " + itemId + "}", Review.class);
        }
    } catch (Exception e) {
      System.out.println("Exception thrown : " + e.getMessage());
    }
    return allDocs;
}

The @RequestParam(required=false) Integer itemId parameter allows you to query the entire review documents or just all reviews associated with a specific itemId. Getting all documents is easy, as there is a built-in API from Cloudant Java library to do that.

Query by itemId is slightly more complex. Cloudant database typically uses the MapReduce mechanism to perform queries. To achieve this, normally you will create an index and save that in the design document (a special Cloudant document). It will only be created once at the first use. Once the index is created, the query can be performed by invoking the index using db.findByIndex().

The returned object will be serialized as a Review entity object in JSON format.

Code review: src/main/resources/application.yml

# Spring properties
spring:
  application:
     name: socialreview-microservice

# Server configuration
server:
  context-path: /micro
  port: 8080

# Cloudant Confiugration
cloudant:
  db: socialreviewdb
  username: 
  password: 
  url: 

This file defines the application configuration such as name of the application, the base URL for the web app and which port it runs on. I also put the Cloudant configuration information in this file. You need to update the cloudant configuration section to fill in the Cloudant instance credentials you created earlier. The ‘db’ property is already set to socialreviewdb to configure the Cloudant client to direct all database requests to that database name.

NOTE: Please use your Cloudant credential ‘url’ or ‘host’ property that doesn’t include the password for your account for the “url” entry in the application.yml file. For instances running on IBM Cloud this will be the ‘host’ value and the protocol. For example: https://xxxx-yyyy-bluemix.cloudant.com.

Code review: src/test/java/socialreview/cloudant/ReviewControllerTest.java

I’ve written a simple integration test case to validate that the connection to Cloudant is successful and able to fetch all the documents. You can follow the instruction later to run the test case.

Build and Run the application

Once you have Cloudant configured, update the src/main/resources/application.yml file for the Cloudant credentials:

  • username
  • password
  • url

NOTE: Please use your Cloudant credential ‘url’ or ‘host’ property that doesn’t include the password for your account for the “url” entry in the application.yml file. For instances running on IBM Cloud this will be the ‘host’ value and the protocol. For example: https://xxxx-yyyy-bluemix.cloudant.com.

Under the repository root directory, run the following command to build and run the application:

$ cd refarch-cloudnative-micro-socialreview
$ ./gradlew build

Make sure that the application build completes successfully. It will package the compiled application under build/libs directory. Now, you can run the application with the following command:

$ java -jar build/libs/micro-socialreview-0.1.0.jar

Yes, the final distribution of the application is in a jar file and all you need to run is to execute the Jar file. The application should be running at port 8080. Open a browser with following URL:

http://localhost:8080/micro/review

This will return all the reviews in the database. You can use Chrome POSTMAN to insert a new review document. Or use the following curl command to insert a review comment:

curl --request POST\
  --url 'http://localhost:8080/micro/review' \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --data @- <<'EOF'
  {"comment": "Nice product",
    "itemId": 13402,
    "rating": 3,
    "reviewer_email":"gangchen@us.ibm.com",
    "reviewer_name": "Gang Chen",
    "review_date": "12/31/2017"}' 
EOF

It should return a Cloudant document ID upon successful execution. You can validate the operation by hitting the GET URL again:

http://localhost:8080/micro/review?itemId=13402

The saved review comment should be returned. Alternatively, you can launch the Cloudant database console and review the documents there as well.

I also provided a simple integration test case that you can run with:

$ ./gradlew clean test

Next: Leveraging containers to simplify deployment and scalability

This post showed you how easily you can build a microservice application to access a Cloudant database using Spring Boot and Cloudant Java client. But it is not that exciting to run the application locally. To demonstrate how the microservice architecture simplifies delivering scalability, the next post in this series will describe how to package the Social Review Spring Boot application as a Docker image, test the Docker container locally, and deploy and run it on IBM Cloud Container platform.

References

More How-tos stories

Deploying to IBM Cloud Private 2.1.0.2 with IBM Cloud Developer Tools CLI

IBM Cloud Private is an application platform for developing and managing on-premises, containerized applications. It is an integrated environment for managing containers that includes the container orchestrator Kubernetes, a private image repository, a management console, and monitoring frameworks.

Continue reading

IBM Cloud Garage Method Field Guide

What does it mean to behave like a startup? How can you transform your business? Field-tested answers to these questions and others are found in the IBM Cloud Garage Method Field Guide. Presented in a fun and visual format, the Field Guide introduces the method and its related practices and architectures that you need to quickly develop quality products.

Continue reading

Hands-on time with IBM Cloud Private

To give you an idea of the IBM Cloud Private environment, the IBM Cloud Garage Method site hosts a hands-on demonstration using actual private servers, allocated on demand for your evaluation. The brief 10 minute demo guides you through the steps of installing a storefront shopping application defined by several Kurbernetes-based microservices. Once installed, you’ll see how to monitor its deployment and running status.

Continue reading