March 24, 2021

Spring Boot Microservices Project Tutorial

In this Spring Boot Microservices Project Tutorial series, you are going to learn how to develop applications with Microservices Architecture using Spring Boot.

Download Source Code

You can download the source code of this project through Github – https://github.com/SaiUpadhyayula/springboot-microservices-project

Spring Cloud Project Overview

The main module which helps us to write microservices using Spring Framework is Spring Cloud, in this tutorial series, we are going to mainly concentrate on the following modules which are part of Spring Cloud:

  • Spring Cloud Config Server
  • Spring Cloud Bus
  • Spring Cloud Netflix Eureka
  • Spring Cloud Circuit Breaker
  • Spring Cloud Sleuth
  • Spring Cloud Gateway
  • Spring Cloud Stream

Spring Cloud Config Server

This module is used to externalize the configuration of our microservices into a centralized place.

If there are any changes in the configuration, our applications should be updated without the need to restart them.

There are many options to implement this Centralized Configuration eg: Using a Git Repository, or using HashiCorp Consul etc.

We are also going to use HashiCorp Vault as one of the backends to maintain the secrets for our application.

Spring Cloud Bus

This module contains a light weight message broker implementation, which is mainly used to broadcast some messages to the other services.

In our project, we will use this module, to broadcast configuration changes in our Config Server.

Spring Cloud Netflix Eureka

This module is used to implement the Service Registry and Discovery Pattern in Microservices architecture.

As there can be many independent Microservices, we need a reliable way to scale the services and provide inter-service communication instead of hard-coding the service information.

Spring Cloud Netflix Eureka module uses Netflix’s Eureka library to provide this functionality.

Other alternatives include Spring Cloud Consul which uses Hashicorp’s Consul or Spring Cloud Zookeeper for Apache Zookeeper

Spring Cloud Circuit Breaker

Inter-service Communication is common in the Microservice architecture, if one of the service is down, the other service which is communicating with it, should be able to handle this failure gracefully.

Spring Cloud Circuit Breaker provides an abstraction over different Circuit Breaker implementations like Reslience4J, Hystrix, Sentinel etc.

In our project, we are going to use Spring Cloud Circuit Breaker with Resilience4J

Spring Cloud Sleuth

In Microservice Architecture, if there is any error, it’s hard to debug and trace it, Spring Cloud Sleuth provides us with the functionality to trace the inter-service calls.

Spring Cloud Gateway

This library helps us to implement the API Gateway pattern, by hiding the complexity of our microservices from the external clients.

If a client want’s to connect to one of our services, all the traffic will be going through the API Gateway and the gateway will route the request to the appropriate service.

This library also handles the cross-cutting concerns like Security, Monitoring, Rate-limiting and Resiliency.

We will secure our microservices using Keycloak as Authorization Server together with the Spring Cloud Gateway.

Spring Cloud Stream

This module mainly allows us to implement asynchronous communication between our microservices using event-driven architecture.

We are going to use RabbitMQ as a message broker to implement some event driven microservices.

Distributed Logging using ELK Stack

Even though, this is not part of the Spring Cloud Stack, we are going to implement Centralized Logging for our microservices using ELK Stack (Elasticsearch, Logstash and Kibana)

Our Sample Project Architecture

As part of this tutorial, we are going to build a Simple Online Shopping Application, the main focus of this tutorial will be to explain the Microservices Architecture and the implementation, so the functionality of the application will be minimal.

We are going to implement 4 Services.

  • Product Service
  • Order Service
  • Inventory Service
  • Notification Service
Microservices Architecture

Creating our First Microservice : Product Service

So let’s go ahead and implement our first microservice (Product Service), as we decided before, we are going to keep the functionality of this service to minimum.

We are going to expose a REST API endpoint which will CREATE and READ products.

Service OperationHTTP METHODService End point
CREATE PRODUCTPOST/api/product/
READ ALL PRODUCTSGET/api/product/

To create the project, let’s go to start.spring.io and create our project based on the following configuration:

Spring Boot Microservices Project - Create Product Service

We are going to use MongoDB as the database backing our Product Service

Configure MongoDB

We have to configure the MongoDB URI Details inside the application.properties file:

####### Mongo Properties ###########
spring.data.mongodb.uri=mongodb://localhost:27017/product-service

If you are not aware of how to work with MongoDB and Spring Boot, have a look at the Spring Boot MongoDB REST API Tutorial

Creating the Create and Read Endpoints

Let’s create the below model class which acts as the domain for the Products.

Product.java

package com.programming.techie.productservice.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.mongodb.core.mapping.Document;

import java.math.BigDecimal;

@Document(value = "product")
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class Product {
    private String id;
    private String name;
    private String description;
    private BigDecimal price;
}

ProductRestController.java

package com.programming.techie.productservice.api;

import com.programming.techie.productservice.model.Product;
import com.programming.techie.productservice.repository.ProductRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.net.URI;
import java.util.List;

@RestController
@RequestMapping("/api/product")
@RequiredArgsConstructor
public class ProductRestController {

    private final ProductRepository productRepository;

    @GetMapping
    public List<Product> getAllProducts() {
        return productRepository.findAll();
    }

    @GetMapping("/{id}")
    public Product getAllProducts(@PathVariable String id) {
        return productRepository.findById(id).orElseThrow(() -> new RuntimeException("Cannot Find Product By ID: " + id));
    }

    @PostMapping
    public ResponseEntity<String> saveProduct(@RequestBody Product product) {
        Product savedProduct = productRepository.insert(product);
        URI uri = ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}")
                .buildAndExpand(savedProduct.getId())
                .toUri();
        return ResponseEntity.created(uri).build();
    }
}

ProductRepository.java

package com.programming.techie.productservice.repository;


import com.programming.techie.productservice.model.Product;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface ProductRepository extends MongoRepository<Product, String> {
}

Testing the APIs

Let’s start the application and test our two Endpoints

We will start of by creating a product, this REST call should return a status 201.

Create Product

Now let’s make a GET call to test whether the created product is returned as a response or not.

Get Product

Creating Order Service

The second service we are going to create is the Order Service, this service only exposes a single POST endpoint called placeOrder

Service OperationEndpoint MethodService Endpoint
PLACE ORDERPOST/api/order

We are going to create the project using the below settings in start.spring.io website.

Spring Boot Microservices Project - Create Order Service

In Order Service, we are going to use MySQL Database, so let’s go ahead and configure it in our project.

Configure MySQL Database

You can configure the following details inside the application.properties file

spring.datasource.url=jdbc:mysql://localhost:3306/order-service
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.datasource.initialization-mode=always
spring.jpa.show-sql=true
spring.datasource.username=root
spring.datasource.password=mysql
server.port=0

After adding the above configuration, make sure to create the schema order-service inside the MySQL database, before starting the application.

As we set the server.port property as 0, the service will run on a Random Port.

This is the minimum configuration, which is needed to get started with the microservices project.

In the next part we will learn how to implement Service Discovery using Spring Cloud Netflix Eureka and Configuration Server using Spring Cloud Config projects.

About the author 

Sai Upadhyayula

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Subscribe now to get the latest updates!