Tutorial: Build a Microservices App With MongoDB
For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt
Tutorial: Build a Microservices App With MongoDB
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:
bash
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:
properties
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:
```java package com.mongodb.configserver;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer;
@EnableConfigServer @SpringBootApplication 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:
properties
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:
```java package com.mongodb.serviceregistry;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication @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:
```yaml 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:
properties
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:
properties
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:
bash
./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:
```text 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:
```java 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:
