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
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
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; }
}
}
Modify appsettings.json
{
"ConnectionStrings": {
"SupplementDB": "mongodb://mongo:27017"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
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);
}
}
}
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",
});
});
On Configure, add the following lines.
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My Supplement V1");
});
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();
}
}
}
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"]
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
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
We should see the following lines if everything works.
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
Let's post a supplement to our API.
Conclusion
I hoped that you enjoyed this tutorial. Here is the link for the project repository.
https://github.com/etnicholson/SupplementAPIAspCoreMongoDB
Top comments (1)
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
"