Create a ASP.NET Web API with MongoDB
Tags: webdev, mongodb, aspdotnet, api
Published: 2024-03-14 15:19:56

Hello everybody,

Continuing my learning path to become a better and more complete developer I challenge myself to learn a little bit about MongoDB that will be consumed by my ASP.NET Core Web Api.

First things first, for those who don´t know what a hell is a MongoDB I will give a short explanation for what I learn in this challenge. 

MongoDB is a NOSQL database and NOSQL means "Not Only SQL". This is because MongoDB is not only a relational database. NOSQL can store unstructured data.

Acording to the definition given by ChatGPT: _"A NoSQL database is a type of database that provides a mechanism for storage and retrieval of data that is modeled in ways other than the tabular relations used in relational databases. It's often used for large-scale distributed data storage and real-time web applications, offering flexibility, scalability, and performance advantages over traditional relational databases." _

So, in practice, MongoDB as NOSQL database is organized like this:
Database -> Collection -> Documents.

The data is stored in a BSON format (Binary Json). Each pieace of this json is a **Document**. So in this example we have three documents. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1p525buik1oymyirycki.png)

And this documents are stored in collections (you can compare a collection like as a table in SQL Relational databases)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ttsx4x4vu5vm9e10lfk.png)

And all this collections are stored in a database!


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xo26wgp3z111hghjq2lx.png)

To start using MongoDB the first thing that you need is the MongoDB "engine". For that I recommend using a image container and run that image in the docker container.
You can find all the images available and also MongoDB here:
[MongoDB container image](https://hub.docker.com/r/bitnami/mongodb)

After pull the image and run it, you need a way to interact with the database. You can choose using for example [MongoDB Shell](https://www.mongodb.com/try/download/shell) or some GUI tool like [MongoDB Compass](https://www.mongodb.com/products/tools/compass).


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/glrxojcl6jgnpeivnx8i.png)

Here you can find a good [MongoDB Cheat Sheet](https://www.mongodb.com/developer/products/mongodb/cheat-sheet/) where you can explore how manipulate the data in MongoDB.

Ok, this was just a brief about MongoDB, now let´s talk about how use MongoDB in a ASP.NET Core Web API.

The first this that you must do is create obviously a new asp.net core web api from your visual studio or vscode.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5gddsl3z3vhqsovsgcah.png)

I will not demonstrate step-by-step everything because it will be boring and also you can download the source code from my [GitHub](https://github.com/iamlobito/CRUD-for-MongoDB). 

After the project is created you need install the nuget package for the MongoDB Driver.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97l21lz6i7cjha5y27eq.png)

I organize my project in that way and I only show here the fundamentals. You can organize in other architecture.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a740ov62apl0gugyrjgj.png)

I have in the Model folder a SuperHero class that represent the document in MongoDB.

Important things here is the data attributes to identify the field Id and map the c# names with MongoDB names.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1jo5l8j24n91zjirmr08.png)

Another thing that you need is to establish connection to the MongoDb. In this example I create a factory class to do that.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jy0o7hqsy3r7wxfzv85k.png)

The configurations of MongoDB connection string is in the appsettings.json.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4hypcb80abjs34u3j4vb.png)

Now, all the magic is in the Repository class. I create a SuperHeroRepository that abstract the data manipulation. In this example the repository do the CRUD operations for MongoDB.

```
public class SuperHeroRepository : ISuperHeroRepository
    {
        private readonly IMongoDbConnectionFactory _connectionFactory;
        private readonly IMongoCollection<SuperHero> _collection;

        public SuperHeroRepository(IMongoDbConnectionFactory connectionFactory)
        {
            _connectionFactory = connectionFactory;

            var database = _connectionFactory.GetDatabase();
            _collection = database.GetCollection<SuperHero>("superhero");

        }

        public async Task<bool> Create(SuperHero hero)
        {
            try
            {
                await _collection.InsertOneAsync(hero);
                return true;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public async Task<bool> Delete(string id)
        {
            var filterDefinition = Builders<SuperHero>.Filter.Eq(a => a.Id, id);
            var result = await _collection.DeleteOneAsync(filterDefinition);
            return result.DeletedCount > 0;
        }

        public async Task<List<SuperHero>> GetAll()
        {
            return await _collection.Find(Builders<SuperHero>.Filter.Empty).ToListAsync();
        }

        public async Task<SuperHero> GetById(string id)
        {
            var filterDefinition = Builders<SuperHero>.Filter.Eq(a => a.Id, id);
            return await _collection.Find(filterDefinition).FirstAsync();
        }

        public async Task<bool> Update(SuperHero hero)
        {
            var filterDefinition = Builders<SuperHero>.Filter.Eq(a=>a.Id, hero.Id);
            var result = await _collection.ReplaceOneAsync(filterDefinition, hero);
            return result.ModifiedCount > 0;
        }
    }
```

Now you need to create your controller that will receive by dependency injection the ISuperHeroRepository. In the Http methods you will call the respective CRUD action.

Lets see the GetAll example:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/69eldlbczx2p2o1kyhpq.png)

Another interesting thing is the way how we filter some query with MongoDB Drive.

In this example, I'm filtering the collection only by the super hero id.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwvj7f35gnu6s5smd2vd.png)

And that's it guys, just sharing my learning with someone.

The source code in the my [GitHub](https://github.com/iamlobito/CRUD-for-MongoDB).

Feel free to clone and happy coding!