Spring Boot Microservice Architecture Part 1

Dennis Brysiuk
NEW IT Engineering
Published in
6 min readDec 2, 2022
Spring Boot Microservice Architecture

This article aims to help you understand Java Spring Boot Microservice Architecture so you can use it in any application. This article covers the pertinent Services, Frameworks, and Configurations needed to create a contemporary Microservice Application.

Architecture Basics

Spring Boot is a Java Framework which simplifies to create stand-alone, productions-grade running Applications. Spring Cloud provides tools for building common patterns in distributed systems. Both Frameworks enable easy implementation of lightweight Microservices and facilitate extensibility, changeability and interchangeability.

In the source code and in production, Microservice Architecture divides each service as a module. Each service is kept as a distinct application that may operate independently of the others. This implies that extremely loaded areas of the program may be readily scaled up and/or maintained by multiple teams.

Individual functionality’ responsibilities are maintained independent and modular by dividing Microservices into 5 levels. More information on Microservice Layer Architecture may be found here.

Each Microservice should be implemented as its own independent module as a Docker container. This enables optimal use of resources, because you can define in a Container what exactly the Service requires to run (Ports, Protocolls, Sockets, CPUs, Memmory, ..) to avoid waste of other ressources from the Server and to improve the security (Configuration files, Credentials, Secrets will be unaccessible even from the same Server). Furthermore a Docker Container is more reliable, because a container will work exactly in same way on any other Systems (e.g. development/production environments/machines).

Because you can define for the Container the resouces that to run optimal the Service requires to run optimal

Initial Spring Boot Microservice

Create a new Project via start.spring.io or through Intellij Spring Initializr with the required dependencies.

  • Discovery Service (Eureka Discovery Client)
  • Internal / External Communication (OpenFeign)
  • Developer Tools (Lombok & Spring Boot DevTools)
  • Presentation Layer (Spring Web)
  • Persistence Layer (Spring Data JPA)
Spring Initializr

And then configure application properties like an application name, port and data source.

demoMicroservice > resources > application.yml

If the Database at the moment is not available you can add in-memory Database (H2).

Discovery Service

All Services register in Discovery Service with their addresses. This achieves the following:

  • proof of heartbeat from all registered services
  • distributing the query load to scaled services
  • services are requested by name and not by address
  • scaling the services require s no additional effort

Spring Cloud Netflix includes a Service Discovery (Eureka) pattern.

Configuration Server

  1. Create Discovery Server via start.spring.io or through Intellij Spring Initializr with Eureka Server dependency.
  2. Add @EnableEurekaServer Annotation to Spring Boot Application class
  3. Apply the following configurations to application.yml (demoDiscoveryServe > resources > application.yml):
eureka:
client:
fetch-registry: false
register-with-eureka: false

The both attributes are set to false because the Eureka Server does not need to register with itself and to read/update the entries to the registry e.g. for own heart beat.

Configuration Client

Apply the following configurations to Microservices in application.yml (DemoMicroservice > resources > application.yml):

eureka:
client:
service-url:
defaultZone: http://localhost:9999/eureka

Property defaultZone should contain Eureka Server Host-Address with path /eureka

Start Discovery Server and the Microservices and you will find now in Eureka UI (default url: localhost:8761, demo url: localhost:9999) all registered Services

Eureka UI

API Gateway

For the communication between the whole Application with the outside world is API Gateway the best solution, it works like a link between the Microservices of the Application and external clients. Spring Cloud Gateway provides a library for building an API Gateway on top of Spring WebFlux.

On the one hand, this results in cleaner code because a genuine service address no longer has to be placed into the program code, but it also allows access to the operations of the Discovery Service and all those below Microservices to be controlled.

Configuration

  1. Create API Gateway Service via start.spring.io or through Intellij Spring Initializr with Spring Cloud Routing Gateway and Eureka Discovery Client dependency.
  2. Apply the following configurations to API Gateway Service in application.yml (DemoApiGateway > resources > application.yml):
spring:
application:
name: demo-api-gateway
cloud:
gateway:
routes:
- id: demo-microservice
uri: lb://DEMO-MICROSERVICE
predicates:
- Path=/**

server:
port: 9090

eureka:
client:
service-url:
defaultZone: http://localhost:9999/eureka

Property gateway.routes.id defines the resource path to access configured resource in gateway.routes.uri and the uri is id of service that registered in Eureka Server (it should be in upper case)

After being registered with Eureka, the API Gateway may now access services using application name, and route setup for DNS or IP addresses is no longer required. One advantage is that the services are secure, and another is that when a service is scaled, no further configuration is necessary.

Services are now accesable trough http://localhost:9090/demo-microservice/ (<API-Gateway-Host-Adresse>/<my-route-path-to-microservice>/<Ressource-Path>)

Internal / External Communication

Microservices are usually only individual modules of an entire application, internal communication between the Microservices is most necessary to provide the whole business case. Furthermore, it is common to communicate with 3rd party applications. Spring Cloud OpenFeign is an abstraction over REST-based calls and adds support on requests or responses in a declarative way with build in REST-Client.

Configuration

  1. Add OpenFeign dependency to Spring Boot Application (to Service that requires internal or external REST-Communication to other Services)
  2. Add @EnableFeignClients Annotation to Spring Boot Application class (DemoOpenFeign > DemoOpenFeignApplication.java):

3. Create Client Interface (DemoOpenFeign > ExternalServiceClient.java / DemoOpenFeign > InternalServiceClient.java) with @FeignClient(name = “client_service_name”, url = “client_url”) Annotation. For more information about package structure see the folowing article: Java Microservice Layer Architecture

Client Interface

and then define CRUD methods with request mapping to internal or external Service (request methods should match with the implementation of requested Client resource)

InternalServiceClient.java Interface
ExternalServiceClient.java Interface

Now you can inject the created Bean into your Service and make REST calls to the external or internal Services (DemoOpenFeign > OpenFeignController.java):

OpenFeignController.java Internal/External Client Interface Injection

Summary

All in all, we have created a solid blueprint for a Microservice Architecture. In the real-world scenario, there is much more that depends to a Microservice Ecosystem, such as

  • API Documentation
  • Config Server
  • Logging and Monitoring
  • Troubleshooting
  • Fault Tolerance

All examples described in the article are available on GitHub.

Have fun and happy coding :)

--

--