In this tutorial, we’re going to build a resilient Java Spring Boot application that scales automatically and also provides high availability with built-in monitoring and diagnostics.
For this, we will be using Microsoft Azure App Service, a PaaS (platform as a service) offering by Microsoft Azure, because it's quite suitable for long running applications and web workloads.
As we want our application to be fully-managed and scaling automatically in the cloud, MongoDB Atlas is a great choice for our data store since it’s a fully-managed, cloud-native database as a service that can also scale up and down automatically in a cost-effective way to meet the needs of any application.
For this particular tutorial, we’ll be using the Spring Initializr plugin for IntelliJ, connect it to a MongoDB Atlas serverless cluster, and deploy the Java Spring Boot application to Azure App Service using the Azure Toolkit for IntelliJ.
Since our Java Spring Boot application is ready, let’s create our MongoDB Atlas cluster with the sample datasets. You can follow the basics tutorial.
1. Let’s create the cluster required by going to the Data Services tab and clicking on the create button.
2. Create a database cluster deployed on Azure. We can use a serverless/dedicated cluster for our production use cases. However, we are creating a shared free cluster for this example.
Select Azure as the cloud provider and select the region of your cluster. Choose the cluster tier (we will be choosing M0 for this tutorial with no backup options), select your cluster name, and click on Create.
3. Load a sample data set, if you’d like, when the cluster is ready by clicking on the ellipsis button.
4. Let’s add some database users who can access the database cluster we just created. Go to the Database Access tab on the left and click on Add new database user.
5. Even if we have added database users, we need to add IPs that can access our database cluster. So let’s add a few IPs to the IP Access List that can access the database cluster over the network, by going to the Network Access tab from the left panel and clicking on Add IP Address Button. We can choose either Add Current IP Address to run and test the app locally or Allow access from anywhere (suitable for development purposes only) to run locally as well as for accessing MongoDB Atlas from the app deployed on Azure App Service.
Please note that we added access from anywhere to start with, but it’s not recommended for production environments as it will lead to a data breach if the connection string that contains the database user details is exposed. We will show you how to use “Peering Connection” in an upcoming section to secure our deployment.
6. Click the Connect button on top of your database cluster, select Connect your application, and copy the MongoDB connection string. We will use this to connect to our database cluster later in the Spring properties files.
Let’s create a new Java Spring Boot application using the IDE IntelliJ and its extension, the Spring Initializr plugin for IntelliJ, which will help us specify the Spring Boot version, JDK, and add the required dependencies.
1. Click File, expand New, and then click Project.
2. In the New Project dialog box, select Spring Initializr, which will take care of generating a Spring Boot project with selected Java versions. Make sure the selected JDK is one of the Microsoft Build of OpenJDK and the Java version also aligns with it, and then click Next.
3. Add dependencies. For this tutorial, we are adding the below required dependencies:
For this example, we will be using the MongoRepository interface which is handy for basic CRUD.
Please note, MongoTemplate APIs can be used for more complex and custom queries and aggregations.
Note: Both the approaches are quite easy to implement and need only a few lines of code.
We have used IntelliJ Ultimate Edition, Spring Boot version 2.7.10, Java 11 (OpenJDK 11u), and IntelliJ Spring Initializr Generator.
We will see the below two dependencies in the generated pom.xml.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependencies>
Please note that we won’t use use https://start.spring.io/ as we need to use the supported JDKs for Azure only.
We have now created a boilerplate Java Spring Boot application and set up our MongoDB Atlas cluster. We can start creating our Java Spring Boot application by using the below package structure and classes.
Let’s create a very simple Person database with the first and last name. We will define a model Person with ID, first name, and last name, and then we will do basic CRUD using MongoRepository interface.
AtlasAzureAppServiceDemoApplication.java
package com.mongo.atlas.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AtlasAzureAppServiceDemoApplication
{
public static void main(String[] args) {
SpringApplication.run(AtlasAzureAppServiceDemoApplication.class, args);
}
}
Please note that we could also define another class(es), use @Configuration, and move the @Value and @Bean to that class.
package com.mongo.atlas.example;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
@SpringBootApplication
public class AtlasAzureAppServiceDemoApplication {
public static void main(String[] args) {
SpringApplication.run(AtlasAzureAppServiceDemoApplication.class, args);
}
@Value("${mongodb.uri}")
private String connectionString;
@Bean
public MongoClient mongoClient() {
CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry);
return MongoClients.create(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(connectionString))
.codecRegistry(codecRegistry)
.build());
}
}
package com.mongo.atlas.example.model;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document("persons")
public class Person {
@Id
@JsonSerialize(using = ToStringSerializer.class)
private ObjectId id;
private String firstName;
private String lastName;
public Person() {
}
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public ObjectId getId() {
return id;
}
public void setId(ObjectId id) {
this.id = id;
}
}
Controller class: This will define different routes and fetch the data accordingly using the repository, and return it to the view.
package com.mongo.atlas.example.controller;
import com.mongo.atlas.example.model.Person;
import com.mongo.atlas.example.repository.PersonRepository;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
@RestController
public class PersonController {
private final PersonRepository personRepository;
public PersonController(PersonRepository personRepository){
this.personRepository = personRepository;
}
@GetMapping("/hello")
public String hello() {
return "hello azure!";
}
@GetMapping("/persons")
public Object getAllPersons(){
try {
return this.personRepository.findAll();
} catch(Exception exception){
return exception;
}
}
@PostMapping("/person")
@ResponseStatus(HttpStatus.CREATED)
public Person createPerson(@RequestBody Person person) {
return this.personRepository.save(person);
}
}
Repository interface: The Repository interface will be used by the controller’s routes to talk to MongoDB. It extends from MongoRepository to model the data as a Person object. For this tutorial, we haven’t done much in this interface, such as passing any filters or query parameters using the Query annotation or any custom implementation.
package com.mongo.atlas.example.repository;
import com.mongo.atlas.example.model.Person;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface PersonRepository extends MongoRepository<Person,String> {
}
Note:
We have created a boilerplate Java Spring Boot application using Spring Initializr and set up our Atlas cluster. Let’s start making a simple application that will connect to our MongoDB Atlas database cluster.
Let’s try to create the files one by one and follow something like the following project structure:
We will see in a bit how we will add secrets to our App Configuration in Microsoft Azure after deploying the application.
Please note that we have specified the database name as well in the MongoDB connection string (mongodb.uri). MongoDB will create a new one, if that database doesn’t exist.
application.properties
spring.config.import=optional:mongodb.properties
mongodb.properties
spring.data.mongodb.uri=mongodb+srv://<<mapped username>>:<<mapped password>>@<<mapped cluster>>.wpeia.mongodb.net/<<databaseName>>?retryWrites=true&w=majority
spring.data.mongodb.database=<<DB>>
spring.data.mongodb.collection=<<Collection>>
However, we can skip spring.data.mongodb.collection as we are using @Document annotation on our model Person.java.
Note : In the case of multiple MongoDB databases and collections, we can use property names such as ‘spring.data.mongodb.db1.uri’, ‘spring.data.mongodb.db1.xxcollection’, and so on, use @Value annotations, and implement the Repository methods as required.
Make sure that the below file is added to .gitignore if you choose to keep your secrets for development purposes.
mongodb.properties
Since we are done creating our database cluster and Java Spring Boot application, let’s run and test it locally.
1. Just click on the green play button near public class AtlasAzureAppServiceDemoApplication in the ProjectNameApplication file, and click Run Application.
2. Try to access it locally once on port 8080, after Run Configuration executes successfully.
3. Let’s insert some data into our collection.
We can also use our person POST route using Postman and the following curl:
curl --location --request POST 'localhost:8080/person' \
--header 'Content-Type: application/json' \
--data-raw '{
"firstName": "ABC",
"lastName": "DEF"
}'
Alternatively, we can use MongoDB Atlas by going to our cluster deployed on Azure and clicking on Browse Collections.
Then, click on Insert Document and insert the document.
We can also use MongoDB Compass to insert the document.
After our Java Spring Boot application runs well locally, we are ready to deploy it on Azure App Service. Let’s follow the steps below in order to do so:
1. Install the Azure Toolkit for IntelliJ plugin and sign into your Azure account using the Azure Explorer sidebar. Then, click the Azure Sign In. Or, navigate to Tools -> Azure -> click Azure Sign In.
2. In the Azure Sign In window, select OAuth 2.0, and then click Sign in. For other sign-in options, see Sign-in instructions for the Azure Toolkit for IntelliJ.
3. In the browser, sign in with your account and then go back to IntelliJ. In the Select Subscriptions dialog box, click on the subscription that you want to use, and then click Select.
4. Under the Project Explorer view, right-click your project, expand Azure, and click Deploy to Azure Web Apps.
5. In the Deploy to Azure dialog box, Click + to create a new Azure web app. You can also choose Web App from the Web App dropdown, if there are existing web apps in your subscription.
6. In the Create WebApp dialog box, specify the following information and click OK:
7. Create the app settings to add your secrets (connection string, dbName, collections, etc.).
Or, you can add the same in Azure Portal by selecting the deployed App Service under App Services under Configuration -> Application Settings -> + New Application Setting after the application is deployed.
8. Click on Apply and then Run to deploy the app service to Azure. The toolkit will start creating a:
And finally, deploy the Java Spring Boot application to the Microsoft Azure App Service and display the hosted URL. You can browse to the domain name selected to see your Azure App service up and running.
Since we mentioned Allow Access from Anywhere over the network is not a recommended practice because it might lead to unexpected security concerns for our data, we would need to configure virtual network peering for our Azure-backed cluster.
Choose Azure as the Cloud Provider on the peering connection popup.
Note: A resource group was created while deploying our Java Spring Boot application.
Open Azure Active Directory to get the Tenant ID
Let’s move to next step under Peering Connection Popup, where we fill in the required details as below:
Now we have to do the final step of peering connection by granting access from Microsoft Azure. Follow the steps given in the Grant Access tab under the Peering Connection popup.
We need to execute the following commands one by one in Microsoft Azure CloudShell.
Please note: We can click on the power shell button in the top right toolbar in the Microsoft Azure portal.
4. Copy the command to create the service principal for MongoDB Atlas and execute as below in the Microsoft Azure CLI or CloudShell (the first icon on the right in the Microsoft Azure portal header).
5. Create a JSON file locally in your local machine with the copied JSON given in Step 2. We can name the file anything we like. We just need to make sure that we reference it accordingly in further steps. For our example, we named it peering.json. Upload the file from your local machine to Azure Cloud Shell as shown below, and then execute the command given in Step 3 in the Grant Access tab with the correct role definition JSON file name.
6. Run the command in Step 4 of the Peering Connection Screenshot to assign the role to the service principal we created in Step 1.
7. Now click on the Validate button as per Step 5 of the Grant Access tab. If the access grant from Microsoft Azure is successful, we will see the below message in green.
8. Click on the Initiate Peering button, and the peering connection will be shown as below in Pending and then the Available state in a few minutes.
Conclusion
In this tutorial, we saw how to connect MongoDB Atlas with Azure App Services using the MongoDB Java driver to build scalable Java Spring Boot web applications.
While we didn't see it in this tutorial, there are many things you can do with the Java driver for MongoDB, such as complex queries with an aggregation pipeline as well as basic CRUD operations.
The code base used in this tutorial can be downloaded from the Github Repository.
To see more of what you can accomplish with MongoDB and Java, check out the MongoDB Developer Center.
With MongoDB Atlas on Microsoft Azure, developers receive access to the most comprehensive, secure, scalable, and cloud–based developer data platform in the market. Now, with the availability of Atlas on the Azure Marketplace, it’s never been easier for users to start building with Atlas while streamlining procurement and billing processes. Get started today through the Atlas on Azure Marketplace listing.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.