DEV Community

etnicholson
etnicholson

Posted on

Developing a CRUDAPI with ASP.NET Core, MongoDB Docker, Swagger.

It has never been easier to use MongoDB and Dotnet core. Docker makes the process even easier by eliminating the need of installing MongoDB on the local machine. For this example, we'll create a supplement store CRUD API.

Prerequisites

I assume that you have .NET Core 2.2 installed and Docker. I've used Visual Studio code to write this API.

Creating the project

Go to your folder of choice, and on your command-line type

dotnet new webapi -n SupplementCRUDAPI
Enter fullscreen mode Exit fullscreen mode

Open the project on visual studio code and the terminal. Let's install all the dependencies that we need for the project.

dotnet add package MongoDB.Driver --version 2.8.1
dotnet add package Swashbuckle.AspNetCore --version 4.0.1
Enter fullscreen mode Exit fullscreen mode

Creating the supplement class and a service

Create a Models folder and class named Supplement with following code

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;


namespace SupplementCRUDAPI.Models
{
    public class Supplement
    {
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string Id { get; set; }

        [BsonElement("Name")]
        public string SupplementName { get; set; }

        [BsonElement("Price")]
        public decimal Price { get; set; }

        [BsonElement("Size")]
        public string Size { get; set; }

        [BsonElement("Type")]
        public string Type { get; set; }

        [BsonElement("Brand")]
        public string Brand { get; set; }
    }
}



Enter fullscreen mode Exit fullscreen mode

Modify appsettings.json

{
  "ConnectionStrings": {
    "SupplementDB": "mongodb://mongo:27017"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}
Enter fullscreen mode Exit fullscreen mode

Create a services folder and class named SupplementService with following code

using Microsoft.Extensions.Configuration;
using MongoDB.Driver;
using SupplementCRUDAPI.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;



namespace SupplementCRUDAPI.Services
{
    public class SupplementService
    {
        private readonly IMongoCollection<Supplement> _supplement;

        public SupplementService(IConfiguration config)
        {
            // Connects to MongoDB.
            var client = new MongoClient(config.GetConnectionString("SupplementDB"));
            // Gets the supplementDB.
            var database = client.GetDatabase("SupplementDB");
            //Fetches the supplement collection.
            _supplement = database.GetCollection<Supplement>("Supplements");
        }

        public async Task<List<Supplement>> Get()
        {
            //Gets all supplements. 
            return await _supplement.Find(s => true).ToListAsync();
        }

        public async Task<Supplement> Get(string id)
        {
            //Get a single supplement. 
            return await _supplement.Find(s => s.Id == id).FirstOrDefaultAsync();
        }

        public async Task<Supplement> Create(Supplement s)
        {
            //Create a supplement.
            await _supplement.InsertOneAsync(s);
            return s;
        }

        public async Task<Supplement> Update(string id, Supplement s)
        {
            // Updates and existing supplement. 
             await _supplement.ReplaceOneAsync(su => su.Id == id, s);
             return s;
        }


        public async Task Remove(string id)
        {
            //Removes a supplement.
            await _supplement.DeleteOneAsync(su => su.Id == id);
        }

    }
}


Enter fullscreen mode Exit fullscreen mode

Modify the Startup

Let's update Startup.cs to add our service and Swagger configuration. On ConfigureServices, add the following lines.

            services.AddScoped<SupplementService>();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info
                {
                    Title = "Supplement API",
                    Version = "v1",
                    Description = "Supplement API tutorial using MongoDB",
                });
            });
Enter fullscreen mode Exit fullscreen mode

On Configure, add the following lines.

            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My Supplement V1");
            });
Enter fullscreen mode Exit fullscreen mode

Create Supplement Controller

Now on the controllers folder add create a new class SupplementController with following code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SupplementCRUDAPI.Models;
using SupplementCRUDAPI.Services;

namespace SupplementCRUDAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SupplementController : ControllerBase
    {
        private readonly SupplementService _supplementService;

        public SupplementController(SupplementService supplementService)
        {
            _supplementService = supplementService;
        }
        // GET: api/Supplement
        [HttpGet]
        public async Task<ActionResult<List<Supplement>>> Get()
        {
            return await _supplementService.Get();
        }

        // GET: api/Supplement/5
        [HttpGet("{id}", Name = "Get")]
        public async Task<ActionResult<Supplement>> Get(string id)
        {
            var s = await _supplementService.Get(id);
            if(s == null)
            {
                return NotFound();
            }

            return s;
        }



        // POST: api/Supplement
        [HttpPost]
        public async Task<ActionResult<Supplement>> Create([FromBody] Supplement s)
        {
            await _supplementService.Create(s);
            return CreatedAtRoute("Get", new { id = s.Id.ToString() }, s);

        }

        // PUT: api/Supplement/5
        [HttpPut("{id}")]
        public  async Task<ActionResult<Supplement>> Put(string id, [FromBody] Supplement su)
        {
            var s = await _supplementService.Get(id);
            if (s == null)
            {
                return NotFound();
            }
            su.Id = s.Id;

            await _supplementService.Update(id, su);
            return CreatedAtRoute("Get", new { id = su.Id.ToString() }, su);
        }

        // DELETE: api/Supplement/5
        [HttpDelete("{id}")]
        public async Task<ActionResult<Supplement>> Delete(string id)
        {
            var s = await _supplementService.Get(id);
            if (s == null)
            {
                return NotFound();
            }

            return NoContent();

        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Docker files

First let's create a file called Dockerfile on our main folder. This file is used to create a docker image to run our project.

 FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "SupplementCRUDAPI.dll"]
Enter fullscreen mode Exit fullscreen mode

On the same folder, create a file named docker-compose.yml. This files use the official image for mongoDB from Docker.

version: '3.1'

services:

  mongo:
    container_name: mongo
    image: mongo
    restart: always
    volumes:
      - ${WEBAPP_STORAGE_HOME}/site:/data/db
      #- ./data:/data/db
    ports:
      - "27017:27017"

  web:
        build: .
        ports:
            - "8000:80"
            - "44348:443"
        depends_on:
            - mongo
        volumes:
            - ${HOME}/.microsoft/usersecrets/:/root/.microsoft/usersecrets
            - ${HOME}/.aspnet/https:/root/.aspnet/https/
        links:
          - mongo
Enter fullscreen mode Exit fullscreen mode

Running the API

We are finally ready to see the API working. First let's run the following commands on the terminal.

docker-compose build
docker-compose up
Enter fullscreen mode Exit fullscreen mode

We should see the following lines if everything works.
Alt text of image

Using Swagger to interact with the API

Swagger is a great tool to visualize and test our API.
Let's navigate to http://localhost:8000/swagger/index.html

Alt text of image

Let's post a supplement to our API.

Alt text of image

Conclusion

I hoped that you enjoyed this tutorial. Here is the link for the project repository.
https://github.com/etnicholson/SupplementAPIAspCoreMongoDB

Top comments (1)

Collapse
 
ronaldoperes profile image
Ronaldo Peres

Hi,

I tried to build it and got this error:
"
/usr/share/dotnet/sdk/2.1.811/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.TargetFrameworkInference.targets(137,5): error NETSDK1045: The current .NET SDK does not support targeting .NET Core 2.2. Either target .NET Core 2.1 or lower, or use a version of the .NET SDK that supports .NET Core 2.2. [/app/SupplementCRUDAPI.csproj]
ERROR: Service 'web' failed to build : The command '/bin/sh -c dotnet restore' returned a non-zero code: 1
"