Develop a Library Web API: Integrating Azure Cosmos DB for MongoDB with ASP.NET Core
As a software developer, you’re always seeking ways to build scalable, high-performance applications. Azure Cosmos DB for MongoDB offers the flexibility of MongoDB with the reliability and global reach of Azure. In this blog, we’ll explore how to integrate Azure Cosmos DB for MongoDB with your ASP.NET Core application, walking through the key steps for setting up a simple API to perform CRUD operations. By leveraging this powerful combination, you can streamline your development process and unlock new possibilities for your data-driven projects.
In our previous blog, we delved into the capabilities of azure cosmos DB for MongoDB using Open MongoDB shell in Azure portal. I highly recommend checking it out to understand the fundamentals.
Topics Covered
Creating an ASP.NET Core Web Application
Connecting to Azure Cosmos DB for MongoDB
Performing CRUD Operations on data
Testing our API with REST Client in Visual Studio Code
Prerequisites
To achieve this goal, ensure you have the following:
Azure Account with Subscriptions: Make sure you have an active Azure account with the necessary subscriptions.
Foundations of Azure Cosmos DB: Review the foundational concepts of Azure Cosmos DB, also discussed in our earlier blog.
Understanding of Azure Cosmos DB For MongoDB: Familiarize yourself with what Azure Cosmos DB for MongoDB is, as covered in our previous blog.
Development Environment: Use Visual Studio Code or Visual Studio as your Integrated Development Environment (IDE). I will be using Visual Studio Code.
.NET SDK: Install the .NET SDK to develop and run your ASP.NET Core applications.
Creating an ASP.NET Core Web Application
An ASP.NET Core web application is a high-performance, cross-platform framework for building modern, cloud-ready web applications and services.
To verify that you have .NET SDK installed, open your terminal and run the following command.
dotnet –version
I will be using .NET 8:
To create an ASP.NET Core web application, start by running the following commands in your terminal. These will generate a new Web API project and open it in Visual Studio Code, a lightweight and versatile code editor.
dotnet new webapi –use-controllers -o LibraryWebApi
cd LibraryWebApi
code .
Now that our project is set up, the next step is to install the MongoDB.Driver package, which provides the necessary tools to interact with a MongoDB database.
The MongoDB.Driver package is an official MongoDB client library for .NET, offering support for connecting, querying, and managing data in MongoDB databases seamlessly within your ASP.NET Core application.
To install the package from NuGet, open the integrated terminal in your project folder and run the following command:
dotnet add package MongoDB.Driver
This will add the MongoDB driver to your project, allowing us to integrate MongoDB operations in our application. The package will be added to LibraryWebApi.csproj
Azure Cosmos DB for MongoDB is a fully managed NoSQL, relational, and vector database designed for modern app development. Known for its low-latency and high-performance capabilities, Azure Cosmos DB for MongoDB enables fast response times. When using it, you can interact with it as if it were a standard MongoDB database, making it easy to integrate into your existing MongoDB-based applications.
In this blog, we’ll demonstrate how to create a simple library web API with CRUD (Create, Read, Update, Delete) operations using Azure Cosmos DB for MongoDB.
Setting up Models
To get started, let’s define our data models. In your solution explorer, at the root of your project, create a Models folder. We’ll begin by adding an Author class that will represent the collection of authors in our database.
Creating the Author Model
Inside the Models folder, add a file named Author.cs and include the following code:
using System;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
namespace LibraryWebApi.Models;
public class Author
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[BsonElement(“Name”)]
public required string Name { get; set; }
[BsonElement(“Bio”)]
public required string Bio { get; set; }
}
This Author class will map to the Authors collection in MongoDB. The Id field is represented as a MongoDB object ID, and the other properties (Name and Bio) represent the fields for each author.
b. Creating the Book Model
Next, add another file in the Models folder named Book.cs. This will represent a collection of books in the database. Here’s the code for the Book class:
using System;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
namespace LibraryWebApi.Models;
public class Book
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[BsonElement(“Title”)]
public required string Title { get; set; }
[BsonElement(“PublishedYear”)]
public DateOnly PublishedYear { get; set; }
[BsonElement(“AuthorId”)]
[BsonRepresentation(BsonType.ObjectId)]
public required string AuthorId { get; set; }
}
The Book class has properties for Title, PublishedYear, and an AuthorId field, which links each book to an author in the Authors collection using a MongoDB object ID.
This is how your file structure should be organized in Visual Studio Code:
Next, you’ll need to create an Azure Cosmos DB resource in the Azure portal. For detailed steps on how to provision Azure Cosmos DB for MongoDB (VCore), refer to the blog post I mentioned earlier. It provides a step-by-step guide to help you set up the resource. Visit the blog here.
I created a cluster named cosmos-mongodb. To connect your application to the newly created resource, go to the settings and retrieve the connection string. You will use this string to establish a connection between your application and the database.
NOTE: Keep your connection string confidential—never expose it in public repositories or share it openly.
In your appsettings.json file, add the connection string you copied from your Azure Cosmos DB resource along with the name of the database you want to create. For this example, we will use LibraryDB, which will automatically be created when the application starts.
Below is an example setup for the appsettings.json:
{
“ConnectionStrings”: {
“MongoDB”: “mongodb+srv://<admin>:<password>@cosmos-mongodb.mongocluster.cosmos.azure.com/?tls=true&authMechanism=SCRAM-SHA-256&retrywrites=false&maxIdleTimeMS=120000”
},
“MongoDB”: {
“DatabaseName”: “LibraryDB”
},
“Logging”: {
“LogLevel”: {
“Default”: “Information”,
“Microsoft.AspNetCore”: “Warning”
}
},
“AllowedHosts”: “*”
}
Now that we have the connection string set up, the next step is to create a DbContext to handle interactions with the database.
Inside the Models folder, create a new folder called DbContext.
In the DbContext folder, add a file named MongoDbContext.cs.
The MongoDbContext class will manage database interactions and provide access to the collections of Books and Authors. Copy the code below and paste in the MongoDbContext.cs.
using System;
using MongoDB.Driver;
namespace LibraryWebApi.Models.DbContext;
public class MongoDbContext
{
private readonly IMongoDatabase _database; // used to interact with the database
public MongoDbContext(IConfiguration configuration)
{
var client = new MongoClient(configuration.GetConnectionString(“MongoDB”)); //connect to the database
_database = client.GetDatabase(configuration[“MongoDB:DatabaseName”]);
}
public IMongoCollection<Book> Books => _database.GetCollection<Book>(“Books”);
public IMongoCollection<Author> Authors => _database.GetCollection<Author>(“Authors”);
}
This should be the project structure and how files should be:
Next, we need to set up the Singleton pattern in Program.cs, which serves as the entry point of the application. The Singleton pattern registers the MongoDbContext class with the dependency injection container, ensuring that only one instance of this class is created and shared across the entire application. This approach is crucial for maintaining a consistent connection to the database and managing data integrity.
To register the MongoDbContext as a singleton service, add the following line of code:
builder.Services.AddSingleton<MongoDbContext>();
Additionally, we need to configure JSON serialization options to prevent the default camel casing during serialization (the conversion of objects to JSON). You can achieve this by modifying the controller settings as follows:
builder.Services.AddControllers()
.AddJsonOptions(
options =>options.JsonSerializerOptions.PropertyNamingPolicy = null);
This configuration will ensure that property names in the JSON output match the original casing in your C# models.
Performing CRUD Operations on data
Next, we will create the controllers necessary for performing CRUD operations on the Books and Authors collections. To do this, create two files: AuthorsController.cs and BooksController.cs, and then add the following code to each file.
AuthorsController.cs File
using System;
using LibraryWebApi.Models;
using LibraryWebApi.Models.DbContext;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
namespace LibraryWebApi.Controllers;
[ApiController]
[Route(“api/[controller]”)]
public class AuthorsController : ControllerBase
{
private readonly MongoDbContext _context;
public AuthorsController(MongoDbContext context) //passing the context to the controller
{
_context = context;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<Author>>> GetAuthors()
{
var authors = await _context.Authors.Find(author => true).ToListAsync();
return Ok(authors);
}
[HttpGet(“{id}”)]
public async Task<ActionResult<Author>> GetAuthor(string id)
{
var author = await _context.Authors.Find(author => author.Id == id).FirstOrDefaultAsync();
if (author == null)
{
return NotFound();
}
return Ok(author);
}
[HttpPost]
public async Task<IActionResult> CreateAuthor(Author author)
{
await _context.Authors.InsertOneAsync(author);
return CreatedAtAction(nameof(GetAuthor), new { id = author.Id }, author);
}
[HttpPut(“{id}”)]
public async Task<IActionResult> UpdateAuthor(string id, Author updatedAuthor)
{
var authorToUpdate = await _context.Authors.Find(author => author.Id == id).FirstOrDefaultAsync();
if (authorToUpdate is null)
{
return NotFound();
}
updatedAuthor.Id = authorToUpdate.Id;
await _context.Authors.ReplaceOneAsync(author => author.Id == id, updatedAuthor);
return NoContent();
}
[HttpDelete(“{id}”)]
public async Task<IActionResult> DeleteAuthor(string id)
{
var result = await _context.Authors.DeleteOneAsync(author => author.Id == id);
if (result.IsAcknowledged && result.DeletedCount > 0)
{
return NoContent();
}
return NotFound();
}
}
b. BooksController.cs File
using System;
using LibraryWebApi.Models;
using LibraryWebApi.Models.DbContext;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
namespace LibraryWebApi.Controllers;
[Route(“api/[controller]”)]
[ApiController]
public class BooksController : ControllerBase
{
public readonly MongoDbContext _context;
public BooksController(MongoDbContext context)
{
_context = context;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<Book>>> GetBooks()
{
var books = await _context.Books.Find(book => true).ToListAsync();
return Ok(books);
}
[HttpGet(“{id}”)]
public async Task<ActionResult<Book>> GetBook(string id)
{
var book = await _context.Books.Find(book => book.Id == id).FirstOrDefaultAsync();
if (book == null)
{
return NotFound();
}
return Ok(book);
}
[HttpPost]
public async Task<IActionResult> CreateBook(Book book)
{
await _context.Books.InsertOneAsync(book);
return CreatedAtAction(nameof(GetBook), new { id = book.Id }, book);
}
[HttpPut(“{id}”)]
public async Task<IActionResult> UpdateBook(string id, Book updatedBook)
{
var bookToUpdate = await _context.Books.Find(book => book.Id == id).FirstOrDefaultAsync();
if (bookToUpdate is null)
{
return NotFound();
}
updatedBook.Id = bookToUpdate.Id;
await _context.Books.ReplaceOneAsync(book => book.Id == id, updatedBook);
return NoContent();
}
[HttpDelete(“{id}”)]
public async Task<IActionResult> DeleteBook(string id)
{
var result = await _context.Books.DeleteOneAsync(book => book.Id == id);
if (result.IsAcknowledged && result.DeletedCount > 0)
{
return NoContent();
}
return NotFound();
}
}
Now build the project to ensure that it can build successfully without any issue. In your terminal execute the following command.
dotnet build
After a successful build, execute the following command in your terminal to run your application.
dotnet run
Your API will run on localhost, and you can launch it in your browser to start testing your application. I recommend enabling Hot Reload, which automatically restarts your API whenever you make changes to your files. Additionally, you can trust HTTPS certificates to run your API securely over HTTPS. These options are optional and can be adjusted based on your preferences.
Create a new file and name it louchSettings.json.
Insert the following code into the file:
NOTE: The port number where your Api will run might not be the same as mine.
{
“profiles”: {
“https”: {
“commandName”: “Project”,
“dotnetRunMessages”: true,
“launchBrowser”: true,
“applicationUrl”: “https://localhost:71992”,
“environmentVariables”: {
“ASPNETCORE_ENVIRONMENT”: “Development”
},
“hotReloadEnabled”: true
}
}
}
With this set-in place, you can run your application with the following command:
dotnet watch run –launch-profile https
Testing our API with REST Client in Visual Studio Code
It’s time to test your API! I recommend using the REST Client extension, which you can install in Visual Studio Code. This extension is efficient because it allows you to test your endpoints directly within your editor, eliminating the need to switch to an external tool.
Create Author:
2. Get All Authors:
3. Get one Author
4. Update an Author:
5. Delete Author
The same applies to Books Collection:
Let’s return to the Azure portal to verify that our database, collections, and data have been successfully stored. Log in to the Azure portal, navigate to the resource you created, and click on Quick Start (Preview) to access the MongoShell.
Open the Mongoshell and, when prompted, enter the password you set up for the cluster.
To see available databases, run this command:
show dbs
To use the available database:
Use LibraryDB
To see all collections in the database:
show collections
To see data in a collection:
db.Authors.find().pretty()
db.Books.find().pretty()
This is the result I got after executing the commands above:
Thank you for taking the time to read my blog!
In this post, we successfully explored how to connect Azure Cosmos DB for MongoDB to an ASP.NET web application through a small project. I encourage you to build on the skills you’ve gained here and add even more features to your applications. I hope you found this learning experience enjoyable and inspiring. Happy coding!
Read More
Create a web API with ASP.NET Core and MongoDB
Query documents in Azure Cosmos DB for MongoDB using .NET
Manage a document in Azure Cosmos DB for MongoDB using .NET
Get started with Azure Cosmos DB for MongoDB using JavaScript
Get started with Azure Cosmos DB for MongoDB and Python
Comparing MongoDB Atlas and Azure Cosmos DB for MongoDB
Azure Cosmos DB Developer Specialty
Microsoft Tech Community – Latest Blogs –Read More