Blog Post

Educator Developer Blog
9 MIN READ

Develop a Library Web API: Integrating Azure Cosmos DB for MongoDB with ASP.NET Core

Brian_Kemboi's avatar
Brian_Kemboi
Brass Contributor
Oct 18, 2024

 

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 

  1. Creating an ASP.NET Core Web Application 
  2. Connecting to Azure Cosmos DB for MongoDB 
  3. Performing CRUD Operations on data 
  4. Testing our API with REST Client in Visual Studio Code   

Prerequisites 

To achieve this goal, ensure you have the following: 

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. 

  1. 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. 

  1. Inside the Models folder, create a new folder called DbContext. 
  2. 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. 

 

  1. 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. 

  1. Create a new file and name it louchSettings.json. 
  2. 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. 

 

 

  1. 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 

 

Updated Oct 15, 2024
Version 1.0
No CommentsBe the first to comment