ASP.NET Core API with Azure Cosmos DB Emulator

Azure Cosmos DB is a fully managed NoSQL database for the modern app development world. Single-digit millisecond response times, and automatic and instant scalability, guarantee the speed at any scale.

Azure Cosmos DB Emulator

The Azure Cosmos DB Emulator provides a local environment that emulates the Azure Cosmos DB service for development purposes in your local PC. Using the Azure Cosmos DB Emulator, you can develop and test your app locally, without creating a paid Azure subscription. When you’re happy with how your application is working in the Azure Cosmos DB Emulator, you can shift to using an Azure Cosmos account in the cloud.

You can download Azure Cosmos DB Emulator here and install it on your pc.

Note: Remember you have to run this emulator before you run the API project.

 

ASP.NET Core API

Step-1: In the NuGet Package Manager, search for and select Microsoft.Azure.Cosmos. Select Install.

Step-2: Add Cosmos DB configuration in appsettings.json:

"CosmosDb": {
    "Account": "Endpoint URI of your Azure Cosmos account",
    "Key": "PRIMARY KEY of your Azure Cosmos account",
    "DatabaseName": "College",
    "ContainerName": "Student"
}

Step-3: Add the following code in Startup.cs:

/// <summary>
/// Creates a Cosmos DB database and a container with the specified partition key. 
/// </summary>
/// <returns></returns>
private static async Task<CosmosDbService> InitializeCosmosClientInstanceAsync(IConfigurationSection configurationSection)
{
     string databaseName = configurationSection.GetSection("DatabaseName").Value;
     string containerName = configurationSection.GetSection("ContainerName").Value;
     string account = configurationSection.GetSection("Account").Value;
     string key = configurationSection.GetSection("Key").Value;
     Microsoft.Azure.Cosmos.CosmosClient client = new Microsoft.Azure.Cosmos.CosmosClient(account, key);
     CosmosDbService cosmosDbService = new CosmosDbService(client, databaseName, containerName);
     Microsoft.Azure.Cosmos.DatabaseResponse database = await client.CreateDatabaseIfNotExistsAsync(databaseName);
     await database.Database.CreateContainerIfNotExistsAsync(containerName, "/id");
     return cosmosDbService;
}

Note: Here, you don’t need to create DB from the emulator portal because we are creating a Database and the Container using the code.

Update the ConfigureServices function in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
     services.AddControllers();
     services.AddSingleton<ICosmosDbService>(InitializeCosmosClientInstanceAsync(Configuration.GetSection("CosmosDb")).GetAwaiter().GetResult());
}

Step-4: Add Student.cs in Models folder:

using Newtonsoft.Json;

namespace Cosmos_CRUD.Models
{
    public class Student
    {
        [JsonProperty(PropertyName = "id")]
        public string Id { get; set; }

        [JsonProperty(PropertyName = "name")]
        public string Name { get; set; }

        [JsonProperty(PropertyName = "address")]
        public string Address { get; set; }

        [JsonProperty(PropertyName = "phone")]
        public string Phone { get; set; }
    }
}

Step-5: Add CosmosDbService.cs in Services folder:

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Cosmos_CRUD.Models;
using Microsoft.Azure.Cosmos;

namespace Cosmos_CRUD.Services
{
    public class CosmosDbService : ICosmosDbService
    {
        private Container _container;

        public CosmosDbService(
            CosmosClient dbClient,
            string databaseName,
            string containerName)
        {
            this._container = dbClient.GetContainer(databaseName, containerName);
        }

        public async Task AddItemAsync(Student item)
        {
            await this._container.CreateItemAsync<Student>(item, new PartitionKey(item.Id));
        }

        public async Task DeleteItemAsync(string id)
        {
            await this._container.DeleteItemAsync<Student>(id, new PartitionKey(id));
        }

        public async Task<Student> GetItemAsync(string id)
        {
            try
            {
                ItemResponse<Student> response = await this._container.ReadItemAsync<Student>(id, new PartitionKey(id));
                return response.Resource;
            }
            catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                return null;
            }

        }

        public async Task<IEnumerable<Student>> GetItemsAsync(string queryString)
        {
            var query = this._container.GetItemQueryIterator<Student>(new QueryDefinition(queryString));
            List<Student> results = new List<Student>();
            while (query.HasMoreResults)
            {
                var response = await query.ReadNextAsync();

                results.AddRange(response.ToList());
            }

            return results;
        }

        public async Task UpdateItemAsync(string id, Student item)
        {
            await this._container.UpsertItemAsync<Student>(item, new PartitionKey(id));
        }
    }
}

Step-6: Add ICosmosDbService.cs in Services folder:

using System.Collections.Generic;
using System.Threading.Tasks;
using Cosmos_CRUD.Models;

namespace Cosmos_CRUD.Services
{
    public interface ICosmosDbService
    {
        Task<IEnumerable<Student>> GetItemsAsync(string query);
        Task<Student> GetItemAsync(string id);
        Task AddItemAsync(Student item);
        Task UpdateItemAsync(string id, Student item);
        Task DeleteItemAsync(string id);
    }
}

Step-6: Add HomeController.cs in Controllers folder:

using Cosmos_CRUD.Models;
using Cosmos_CRUD.Services;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Cosmos_CRUD.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        private readonly ICosmosDbService _cosmosDbService;
        public HomeController(ICosmosDbService cosmosDbService)
        {
            _cosmosDbService = cosmosDbService;
        }

        [HttpGet]
        [Route("GetAll")]
        public async Task<IEnumerable<Student>> GetAll()
        {
            return await _cosmosDbService.GetItemsAsync("SELECT * FROM c");
        }

        [HttpGet]
        [Route("Get/{id}")]
        public async Task<Student> Get(string id)
        {
            return await _cosmosDbService.GetItemAsync(id);
        }

        [HttpPost]
        [Route("Insert")]
        public async Task<string> Insert(Student student)
        {
            if (ModelState.IsValid)
            {
                student.Id = Guid.NewGuid().ToString();
                await _cosmosDbService.AddItemAsync(student);
                return student.Id;
            }
            else
                return "";
        }

        [HttpPost]
        [Route("Update")]
        public async Task<string> Update(Student student)
        {
            if (ModelState.IsValid)
            {
                await _cosmosDbService.UpdateItemAsync(student.Id, student);
                return student.Id;
            }
            else
                return "";
        }

        [HttpPost]
        [Route("Delete/{id}")]
        public async Task<string> Delete(string id)
        {
            await _cosmosDbService.DeleteItemAsync(id);
            return id + " - Deleted successfully.";
        }
    }
}

 

So, now our API is ready to perform CRUD operation in the College Db and the Container is Student.

I have run the API calls in the Postman. Please review the following:

  • /api/Home/GetAll:

  • /api/Home/Get/{id}:

  • /api/Home/Insert:

  • /api/Home/Update:

  • /api/Home/Delete/{id}:

 

Let me know in the comments if you face any difficulties.

Thank you.

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories