RESTful WEB API for CRUD operations in MongoDB using .Net

As you already know, MongoDB is the future of modern web applications amd it is very important for .NET developers to get their hands on MongoDB drivers.
In this we are to going to create Web APIs for manipulating and performing CRUD operations on student resource of our project.

Application Architecture

Application we are going to build is very simple we are going to use MongoDB as our database and will create .NET Web APIs for data operation on MongoDB and there will be a test client to use our Web APIs.

Database Setup

Creating database is a piece of cake in MongoDB. You can refer my previous article for more details. We just need to write below command to create database named studentsDB and collection named students:
use studentsDB
 db.students.insert({ "_id" : 1, "RollNo" : "rol1", "Name" : "vikas", "Class" : "12th" })
Above command will create collection and insert a record on it.
For the sake of simplicity I am only creating one collection ‘students’ and will perform all our operations on this collection.

Creating Web API

Open your visual studio to create a new project, I am using Visual Studio 2013 community edition. You can use visual studio 2013 or above version for the same.
Steps:
1. Select Web -> ASP.NET MVC 4 Web Application.
2. Give Project Name: Students.API
3. Select Web API and click OK.
4. That’s the power of Visual Studio; within few clicks we are ready with a dummy Web API project. By default, controllers contain Home and Value Controller you can choose to delete them because we will create our own student controller to manage client calls. But before that, there are other things we need to take care of. It’s just the beginning of our fun-filled journey.

Creating Data Model

Data Model is the project in our solution which contains Models of our application.

Steps

1. Add a new class library project to your solution and name it Students.DataModel.
2. Delete the default Class1.cs because we won’t need it.
3. Create a folder named Models and add a class named Student.cs to it. This class is going to be our Model Class for Student entity of students collection.
4. Similarly, create a folder named GenericRepository and add Repository.cs class to it.
5. In the same manner create one more folder named UnitOfWork and add UnitOfWork.cs to it.
6. Before adding any code to Student class we need to add reference of official MongoDB drivers to our Data Model Project so that we can communicate to MongoDB.
7. Right Click on the Data Model project and select Manage NuGet Packages and search for MongoDB.
8. Replace the code of Student Class with below code:
using MongoDB.Bson.Serialization.Attributes;

namespace Students.DataModel.Models
{
    public class Student
    {
        [BsonElement("_id")]
        public int StudentID { get; set; }
        public string RollNo { get; set; }
        public string Name { get; set; }
        public string Class { get; set; }
        
    }
}
Here the [BsonElement("_id")] attribute tells MongoDB that StudentID is going to be used as unique key i.e. _id in student collection. The rest is very simple. No need to explain anything.
9. Replace code of Repository Class with the following code:
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Students.DataModel.Repository
{
    public class Repository<T>  where T : class
    {
        private MongoDatabase _database;
        private string _tableName;
        private MongoCollection<T> _collection;

        // constructor to initialise database and table/collection  
        public Repository(MongoDatabase db, string tblName)
        {
            _database = db;
            _tableName = tblName;
            _collection = _database.GetCollection<T>(tblName);
        }


        /// <summary>
        /// Generic Get method to get record on the basis of id
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public T Get(int i)
        {
           return _collection.FindOneById(i);
 
        }

       /// <summary>
       /// Get all records 
       /// </summary>
       /// <returns></returns>
        public IQueryable<T> GetAll()
        {
            MongoCursor<T> cursor =_collection.FindAll();
            return cursor.AsQueryable<T>();

        }

        /// <summary>
        /// Generic add method to insert enities to collection 
        /// </summary>
        /// <param name="entity"></param>
        public void Add(T entity)
        {
            _collection.Insert(entity);
        }

        /// <summary>
        /// Generic delete method to delete record on the basis of id
        /// </summary>
        /// <param name="queryExpression"></param>
        /// <param name="id"></param>
        public  void Delete(Expression<Func<T, int>> queryExpression, int id)
        {
            var query = Query<T>.EQ(queryExpression, id);
            _collection.Remove(query);
        }

        /// <summary>
        ///  Generic update method to delete record on the basis of id
        /// </summary>
        /// <param name="queryExpression"></param>
        /// <param name="id"></param>
        /// <param name="entity"></param>
        public void Update(Expression<Func<T, int>> queryExpression, int id,T entity)
        {
            var query = Query<T>.EQ(queryExpression, id);
            _collection.Update(query, Update<T>.Replace(entity));
        }

    }
}
The above class is self-explanatory, it is a generic class to handle operations on various collections and different entities. We have created five generic methods to perform CRUD operation on any collection.
The first method will grab one document from the collection initialized on constructor on the basis of integer id provided as the parameter.
The second method will grab all records from the collection as queryable. See how the FindAll() method returns MongoCursor which then will return entities as queryable.
The third method, as the name suggests, will add one entity received as parameter to specified collection.
The fourth method will delete record on the basis of id provided. Firstly, it will query the collection to search for the document with the id provided and then delete the same.
The fifth method will query the collection on the basis of id and then update (replace the document found with the new document provided). Id of the old document should match the new document provided.
10. Now it’s time to replace UnitOfWork Class with the following code:
using MongoDB.Driver;
using Students.DataModel.Models;
using Students.DataModel.Repository;
using System.Configuration;

namespace Students.DataModel.UnitOfWork
{
    public class UnitOfWork
    {
        private MongoDatabase _database;

        protected Repository<Student> _students;

        public UnitOfWork()
        {
            var connectionString = ConfigurationManager.AppSettings["MongoDBConectionString"];
            var client = new MongoClient(connectionString);
            var server = client.GetServer();
            var databaseName = ConfigurationManager.AppSettings["MongoDBDatabaseName"];
            _database = server.GetDatabase(databaseName);
        }
        public Repository<Student> Students
        {
            get
            {
                if (_students == null)
                    _students = new Repository<Student>(_database, "students");

                return _students;
            }
        }
    }
}
Here we created UnitOfWork class which establishes connection with the MongoDB Server and the database we want to perform CRUD operations and it will simply return the Repository as its property.
11. Add new key value pair in the appSettings section to web config of Students.API project.
<appSettings>
    <add key="MongoDBConectionString" value="mongodb://localhost:27017" />
    <add key="MongoDBDatabaseName" value="studentsDB"/>
Note: you would need to resolve compilation error if any, by adding appropriate namespace and references to your project.

Creating Services

Now we need services to handle StudentsUnitOfWork and call appropriate method to communicate with the database and return the result to our controller.
Steps:
1. Add new class library project to your solution named Students.Services.
2. Add an interface named IStudentService and a class StudentService that will inherit the interface added to the Students.Services.
3. Replace interface code with the following code:
using Students.DataModel.Models;
using System.Linq;

namespace Students.Services
{
    public interface IStudentService
    {
        void Insert(Student student);
        Student Get(int i);
        IQueryable<Student> GetAll();
        void Delete(int id);
        void Update(Student student);
    }
}
4. It’s time to add code to your StudentService class and as it will inherit the above interface we will have to provide the body for all the methods of interface. Let’s replace service class code with the following code:
using Students.DataModel.Models;
using Students.DataModel.UnitOfWork;
using System.Linq;

namespace Students.Services
{
    public class StudentService : IStudentService
    {
        private readonly StudentsUnitOfWork _sUnitOfwork;

        public StudentService()
        {
            _sUnitOfwork = new StudentsUnitOfWork();
        }

        public Student Get(int i)
        {
           return _sUnitOfwork.Students.Get(i);
        }

        public IQueryable<Student> GetAll()
        {
            return _sUnitOfwork.Students.GetAll();
        }

        public void Delete(int id)
        {
            _sUnitOfwork.Students.Delete(s => s.StudentID,id);
        }

        public void Insert(Student student)
        {
            _sUnitOfwork.Students.Add(student);
        }

        public void Update(Student student)
        {
            _sUnitOfwork.Students.Update(s => s.StudentID,student.StudentID, student);
        }

    }
}
Let’s understand what we are trying to achieve with above code.
We have created a private object of StudentsUnitOfWork and initialized it in the constructor. In our first method Get, we are calling generic Get method of StudentsUnitOfWork property’s students (StudentsRepository) which will return Student object. Similarly, the second method will return IQueryable objects of student class. The insert method is pretty simple. We are sending a new student object to be added to the StudentsUnitOfWork. Delete and Update method are similar in the sense that in both method lamba expression is used which will delete and update records respectively.

Updating Web API

Let me remind you that our Web API project comes with default controllers Home and Value Controller we need to create our own controller named StudentController for creating RESTful Web APIs. So below is the steps for the same:
1. Right-Click on the controllers folder in the Students.API project and new controller.
2. Replace the default code of controller with the following code:
using System.Linq;
using System.Web.Http;
using Students.DataModel.Models;
using Students.Services;
using System.Net.Http;
using System.Net;


namespace Students.API.Controllers
{
    public class StudentsController : ApiController
    {
        private readonly IStudentService _studentService;

        public StudentsController()
        {
            _studentService = new StudentService();
        }

// GET api/student/id
        public HttpResponseMessage Get(int id)
        {

            var student= _studentService.Get(id);
            if(student!=null)
                return Request.CreateResponse(HttpStatusCode.OK, student);
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Student not found for provided id.");
        }

        public HttpResponseMessage GetAll()
        {
            var students= _studentService.GetAll();
            if (students.Any())
                return Request.CreateResponse(HttpStatusCode.OK, students);
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No students found.");
        }
     
        public void Post([FromBody]Student student)
        {
            _studentService.Insert(student);

        }
        public void Delete(int id)
        {
            _studentService.Delete(id);
        }
        public void Put([FromBody]Student student)
        {
            _studentService.Update(student);
        }
    }
}
We created five methods or we can say five APIs for handling CRUD operation. In the constructor we created object of the StudentService and in controllers’ method we will call service methods for handling client request.
The first method will make calls to service to fetch records on the basis of id provided on the URL.
The second method will make call to service to fetch all records.
The third method will post a new record to service to insert in the database.
The fourth method will make calls to service to delete record from database.
The fifth method will make call to service to update record in the database.
All the above methods are HTTP VERBS and Web API will itself recognize request with the name of the VERB.
Now our APIs are ready to test, save the solution and build the solution. But how are we going to test our APIs? Not to worry we don’t need to create a full-fledged client for this. Right the Web API project and select Manage NuGet Packages and search for test client and install ‘A simple Test Client for ASP.NET Web API’.
It will install a test client to test our APIs. Yes, we are ready to test now, but before running your application make sure your MongoDB server is running.

Testing Web API

Steps to test Web API:
1. Run your application.
2. ASP.NET Web API Home page will be loaded on the browser, click on the API link to see the list of APIs created by you.
3. Click on the APIs link to test them. If you click on any of the link it will redirect you the documentation page of the API clicked, there you will see a Test API button on the right corner of the screen. Click on the Test API button to test the API.

please refer this link. for full details.

No comments:

Post a Comment

Genuine websites to earn money.

If you are interested in PTC sites then this article is for you. I have personally tried many of the sites and found that the best thing ...