How to create CRUD application using Azure Cosmos DB for MongoDB applications?
Azure Cosmos DB databases can be used as the data store for apps written for MongoDB. This means that by using existing drivers, your application written for MongoDB can now communicate with Cosmos DB and use Cosmos DB databases instead of MongoDB databases. In this post, I’ll tell you how to create CRUD application using Azure Cosmos DB for MongoDB applications.
Application
The project code used in this post is located on GitHub, so feel free to use it for learning purpose. I’ll be using ASP.NET MVC framework for this post.
Azure Cosmos DB & Setup
Azure Cosmos DB is Microsoft’s globally distributed, multi-model database service. To work with DocumentDB, an Azure account is required which is free for 30 days. If you already have an Azure Cosmos DB service account, then you can directly create a database. If not, please create this account by using the azure portal by going through New > Databases > Azure Cosmos DB.
For the new account setup, give a unique id for this resource in a new or existing resource group. For API, choose MongoDB as this is the focus of this post and choose a location. It will take few seconds to create this service and once the account is ready, you are all set to create a database.
MongoDB allow us to create a database and have collections inside it. Just to note that, a collection as a concept is not same as a table in relational database. As such there is no schema for the data that will be stored, the data can be of any shape. Create a new database called `CourseDb` and create a collection named `Courses` inside the same database. You may name these anything else as well. The same portal can also be used to view, create, edit, delete documents using Data Explorer (Preview) feature.
I’m not going to paste any ASP.NET MVC code here and it will make the post lengthy. Please look at the repository for this purpose. To keep this post simple and focus on the CRUD (create, read update, delete), I’m going to create a simple Course application that is used to manage courses, say in a school or college or university. The definition of Course type looks like following:
public class Course
{
[BsonId(IdGenerator = typeof(CombGuidGenerator))]
public Guid Id { get; set; }
[BsonElement("Title")]
public string Title { get; set; }
[BsonElement("Modules")]
public string Modules { get; set; }
[BsonElement("Completed")]
public bool Completed { get; set; }
}
This class is quite simple and the properties are decorated with attributes such as `BsonId` to indicate that property `Id` should be generated automatically and `BsonElement` to define correct property name that will be used to map with the result that Azure will give us back when using MongoDB.
MongoDB Context
To consume MongoDB from Azure in your ASP.NET MVC application, a package named `MongoDB.Driver` is required in the project using Nuget Package Manager. I’ve used version 2.4.4. This package gives us a `MongoClient` class that can be used to talk to MongoDB in any Azure instance by just providing the host, port, username, database name and password.
Select Connection String in portal and all the information mentioned above. As such actions like create, update and delete are required for application, use read-write keys. Copy these values in the `appSettings` of web.config file, like this:
</appSettings>
<add key="CosmosDbAccountUsername" value="your storage account name"/>
<add key="CosmosDbAccountPassword" value="your storage account password"/>
<add key="CosmosDbAccountHost" value="your storage account host"/>
<add key="CosmosDbAccountPort" value="your storage account host" />
<add key="DatabaseName" value="coursesdb" />
<add key="CollectionName" value="courses" />
</appSettings>
Let us now see the implementation of MongoDB context class named as `DbContext`:
public class DbContext
{
private readonly string _username = ConfigurationManager.AppSettings.Get("CosmosDbAccountUsername");
private readonly string _password = ConfigurationManager.AppSettings.Get("CosmosDbAccountPassword");
private readonly string _host = ConfigurationManager.AppSettings.Get("CosmosDbAccountHost");
private readonly int _port = Convert.ToInt32(ConfigurationManager.AppSettings.Get("CosmosDbAccountPort"));
private readonly string _databaseName = ConfigurationManager.AppSettings.Get("DatabaseName");
public readonly string CollectionName = ConfigurationManager.AppSettings.Get("CollectionName");
public IMongoDatabase Database { get; private set; }
public DbContext()
{
MongoClientSettings settings = GetSettings();
MongoIdentity identity = new MongoInternalIdentity(_databaseName, _username);
MongoIdentityEvidence evidence = new PasswordEvidence(_password);
settings.Credentials = new List<MongoCredential>()
{
new MongoCredential("SCRAM-SHA-1", identity, evidence)
};
var mongoClient = new MongoClient(settings);
Database = mongoClient.GetDatabase(_databaseName);
Database.CreateCollection(CollectionName);
}
private MongoClientSettings GetSettings()
{
var settings = new MongoClientSettings
{
Server = new MongoServerAddress(_host, _port),
UseSsl = true,
SslSettings = new SslSettings { EnabledSslProtocols = SslProtocols.Tls12 }
};
return settings;
}
}
Repository
The context is then provided to the repository to handle all create, read, update and delete (CRUD) operations. The definition of this repository is provided below:
public class CoursesRepository
{
private readonly DbContext _dbContext;
public CoursesRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public Course GetCourse(Guid id)
{
IMongoCollection<Course> collection = GetCollection();
Course course = collection.AsQueryable().FirstOrDefault(c => c.Id.Equals(id));
return course;
}
public List<Course> GetCourses()
{
IMongoCollection<Course> collection = GetCollection();
return collection.Find(new BsonDocument()).ToList();
}
public async Task CreateCourseAsync(Course course)
{
IMongoCollection<Course> collection = GetCollection();
await collection.InsertOneAsync(course);
}
public async Task<ReplaceOneResult> UpdateCourseAsync(Guid id, Course course)
{
IMongoCollection<Course> collection = GetCollection();
return await collection.ReplaceOneAsync(c => c.Id.Equals(id), course);
}
public async Task<DeleteResult> DeleteCourseAsync(Guid id)
{
IMongoCollection<Course> collection = GetCollection();
return await collection.DeleteOneAsync(c => c.Id.Equals(id));
}
private IMongoCollection<Course> GetCollection()
{
return _dbContext.Database.GetCollection<Course>(_dbContext.CollectionName);
}
}
Next, the controller consumes this context and repository as shown below. I’ve not pasted whole controller below so, please refer to the linked repository for full source code.
public class CoursesController : Controller
{
private CoursesRepository _coursesRepository;
public CoursesController()
{
var dbContext = new DbContext();
_coursesRepository = new CoursesRepository(dbContext);
}
}
This sums up my post. For any issues, please use my repository or comment here. I hope this post easily explains how to create a CRUD application using Azure Cosmos DB for MongoDB applications. Please subscribe to my website to get more updates on similar topics.
