Overview
This tutorial shows how to build a microservices architecture by using Spring Boot, Spring Cloud, and MongoDB. Specifically, this tutorial walks you through creating multiple services that work together to form a complete application.
You can find the complete source code in the following GitHub repositories:
Spring Boot
Spring Boot is a framework built on top of the Spring Framework. It adds auto-configuration, defaults, and production-ready features to simplify building Spring-based Java applications, including integration with Spring Data MongoDB. For more information, see the Spring Boot documentation.
Spring Cloud
Spring Cloud is a collection of tools for building distributed systems and microservices. It provides features for configuration management, service discovery, and intelligent routing. For more information, see the Spring Cloud documentation.
Tutorial
This tutorial shows how to perform the following actions:
Verify the prerequisites
Clone the example repositories
Set up a config server
Set up a service registry
Configure an API gateway
Create MongoDB microservices
Test the REST APIs
Verify the prerequisites.
Before you begin, ensure you have the following installed:
Java Development Kit (JDK) 21 or later. You can download the JDK from the Oracle website.
Git
MongoDB (two deployments for local development). To learn how to set up MongoDB locally, see the Create a Local Atlas Deployment with Docker guide.
Clone the example repositories.
Clone the microservices application and configuration repositories by running the following commands:
git clone git@github.com:mongodb-developer/microservices-architecture-mongodb.git git clone git@github.com:mongodb-developer/microservices-architecture-mongodb-config-repo.git
Follow the instructions in the README.md
file of the microservices-architecture-mongodb repository
to start each service.
Set up a config server.
A config server stores all configuration files for your microservices within a single repository.
The config server configuration is defined in the
microservices-architecture-mongodb/config-server/src/main/resources/application.properties
file:
spring.application.name=config-server server.port=8888 spring.cloud.config.server.git.uri=${HOME}/Work/microservices-architecture-mongodb-config-repo spring.cloud.config.label=main
This configuration specifies the location of the Git repository that stores your microservices configuration and the branch to use.
The config server application is defined in the following
Java class located in the
microservices-architecture-mongodb/config-server/src/main/java/com/mongodb/configserver/
directory:
package com.mongodb.configserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
Note
The @EnableConfigServer annotation enables the config
server functionality in your Spring Boot application.
Set up a service registry.
A service registry tracks which microservices are running and their locations. Other services use this information to communicate with the microservices they need.
The service registry configuration is defined in the following properties file:
spring.application.name=service-registry server.port=8761 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false
The last two properties prevent the service registry from registering to itself.
The service registry application is defined in the following
Java class located in the
microservices-architecture-mongodb/service-registry/src/main/java/com/mongodb/serviceregistry/
directory:
package com.mongodb.serviceregistry; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; public class ServiceRegistryApplication { public static void main(String[] args) { SpringApplication.run(ServiceRegistryApplication.class, args); } }
Note
The @EnableEurekaServer annotation enables the service
registry functionality in your Spring Boot application.
Configure an API gateway.
An API gateway provides a single entry point to access all your microservices. The gateway distributes requests across multiple microservices and handles security, monitoring, and other concerns.
The API gateway configuration is defined in the
microservices-architecture-mongodb/api-gateway/src/main/resources/application.yml
file:
server: port: 8080 spring: application: name: api-gateway cloud: gateway: routes: - id: company-service uri: lb://company-service predicates: - Path=/api/company/**,/api/companies - id: employee-service uri: lb://employee-service predicates: - Path=/api/employee/**,/api/employees eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://localhost:8761/eureka/ instance: hostname: localhost
This configuration defines routes for the company and employee services and registers the gateway with the service registry.
Create MongoDB microservices.
This application includes two microservices: a company service and an employee service. Each microservice connects to its own MongoDB instance to maintain independence.
The company service configuration is defined in the
microservices-architecture-mongodb-config-repo/company-service.properties file:
spring.data.mongodb.uri=${MONGODB_URI_1:mongodb://localhost:27017} spring.threads.virtual.enabled=true management.endpoints.web.exposure.include=* management.info.env.enabled=true info.app.name=Company Microservice info.app.java.version=21 info.app.type=Spring Boot server.port=8081 eureka.client.register-with-eureka=true eureka.client.fetch-registry=true eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ eureka.instance.hostname=localhost
The employee service configuration is defined in the
microservices-architecture-mongodb-config-repo/employee-service.properties file:
spring.data.mongodb.uri=${MONGODB_URI_2:mongodb://localhost:27018} spring.threads.virtual.enabled=true management.endpoints.web.exposure.include=* management.info.env.enabled=true info.app.name=Employee Microservice info.app.java.version=21 info.app.type=Spring Boot server.port=8082 eureka.client.register-with-eureka=true eureka.client.fetch-registry=true eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ eureka.instance.hostname=localhost
Note
For local development, the company service connects to
MongoDB on port 27017 and the employee service connects to
MongoDB on port 27018. For production, use separate
MongoDB Atlas clusters and set the connection strings by
using the MONGODB_URI_1 and MONGODB_URI_2
environment variables.
Test the REST APIs.
After you start all services, verify that your microservices architecture works correctly by ensuring that the following services are running:
Config server on port 8888
Service registry on port 8761
API gateway on port 8080
Company service on port 8081
Employee service on port 8082
Also ensure you have two MongoDB instances running on ports 27017 and 27018, or two MongoDB Atlas clusters.
Run the test script by running the following command:
./2_api-tests.sh
The script creates companies and employees, then retrieves them by using the REST API. The output returned by the script resembles the following:
DELETE Companies 2 DELETE Employees 2 POST Company 'MongoDB' POST Company 'Google' GET Company 'MongoDB' by 'id' { "id": "661aac7904e1bf066ee8e214", "name": "MongoDB", "headquarters": "New York", "created": "2009-02-11T00:00:00.000+00:00" } GET Company 'Google' by 'name' { "id": "661aac7904e1bf066ee8e216", "name": "Google", "headquarters": "Mountain View", "created": "1998-09-04T00:00:00.000+00:00" } GET Companies [ { "id": "661aac7904e1bf066ee8e214", "name": "MongoDB", "headquarters": "New York", "created": "2009-02-11T00:00:00.000+00:00" }, { "id": "661aac7904e1bf066ee8e216", "name": "Google", "headquarters": "Mountain View", "created": "1998-09-04T00:00:00.000+00:00" } ] POST Employee Maxime POST Employee Tim GET Employee 'Maxime' by 'id' { "id": "661aac79cf04401110c03516", "firstName": "Maxime", "lastName": "Beugnet", "company": "Google", "headquarters": "Mountain View", "created": "1998-09-04T00:00:00.000+00:00", "joined": "2018-02-12T00:00:00.000+00:00", "salary": 2468 } GET Employee 'Tim' by 'id' { "id": "661aac79cf04401110c03518", "firstName": "Tim", "lastName": "Kelly", "company": "MongoDB", "headquarters": "New York", "created": "2009-02-11T00:00:00.000+00:00", "joined": "2023-08-23T00:00:00.000+00:00", "salary": 13579 } GET Employees [ { "id": "661aac79cf04401110c03516", "firstName": "Maxime", "lastName": "Beugnet", "company": "Google", "headquarters": "Mountain View", "created": "1998-09-04T00:00:00.000+00:00", "joined": "2018-02-12T00:00:00.000+00:00", "salary": 2468 }, { "id": "661aac79cf04401110c03518", "firstName": "Tim", "lastName": "Kelly", "company": "MongoDB", "headquarters": "New York", "created": "2009-02-11T00:00:00.000+00:00", "joined": "2023-08-23T00:00:00.000+00:00", "salary": 13579 } ]
The employee service queries the company service to retrieve company details. The following code shows how the employee service communicates with the company service through the service registry:
private CompanyDTO getCompany(String company) { String url = "http://company-service/api/company/name/"; CompanyDTO companyDTO = restTemplate.getForObject(url + company, CompanyDTO.class); if (companyDTO == null) { throw new EntityNotFoundException("Company not found: ", company); } return companyDTO; }
The URL references the company service by name rather than by IP address and port, which confirms that the service registry works correctly.
Additional Resources
To learn more about building microservices with Spring and MongoDB, see the following resources: