In this tutorial I will show you how to develop an ASP.NET 8.0 Minimal API application that interacts with MongoDB. In order to proceed you will need the following pre-requisites:
- Docker - used to host MongoDB. This is my preferred approach because it is quick and does not take too many resources on the host computer.
- .NET 8.0
- Visual Studio Code
The Database
Run the following command in a terminal window to start a MongoDB container named mdb:
docker run -p 27777:27017 --name mgo -d mongo:4.1.6
You can verify that the container is running by typing the following command in a terminal window:
docker ps -a
Let us start a bash session inside the container so that we can create a database and add some sample data to it. Enter the following command to start an interactive bash session inside the container:
docker exec -it mgo bash
We can then use the mongo command line interface (CLI) to create a database named school-db and then add some sample data to a collection of students. Type the following command:
mongo
This takes you into a mongo session command prompt. Enter the following command to create a database named school-db:
use school-db
Next, let's create a collection named students and add to it six sample students:
db.Students.insertMany([{'FirstName':'Sue','LastName':'Fox','School':'Business'},{'FirstName':'Tom','LastName':'Max','School':'Mining'},{'FirstName':'Ann','LastName':'Lee','School':'Nursing'},{'FirstName':'Joe','LastName':'Roy','School':'Tourism'},{'FirstName':'Jan','LastName':'Ash','School':'Communications'},{'FirstName':'Eva','LastName':'Day','School':'Medicine'},]);
You can retrieve the list of students with the following command:
db.Students.find().pretty();
To exit the mongo command prompt by typing:
exit
You can also exit the bash session and return to the host operating system by typing:
exit
Creating an ASP.NET 8.0 Minimal Web API application
Create an ASP.NET 8.0 Minimal Web API application. This is accomplished by entering this command:
dotnet new webapi -f net8.0 -o AspMongoApi
Let's see what our application looks like. Run the application by executing:
cd AspMongoApidotnet run
The above command builds and runs the application in a web server. Point your browser to https://localhost:????/weatherforecast (Where ???? is your port number). This is what you should see:
Stop the web server by hitting CTRL+C on the keyboard.
Building the Students API
Add the MongoDB driver Nuget package with the following command:
dotnet add package MongoDB.Driver
Now that we have the driver, we can proceed with coding our Minimal API. I will use Visual Studio Code because it is operating system agnostic. To load your application workspace into VS Code, simply type in the following command from the root folder of your application:
code .
We need a Student class to represent the schema for student documents in a Students collection in the MongoDB school-db database. Create a Models folder. Inside the Models folder, add a file named Student.cs with the following code:
using MongoDB.Bson;using MongoDB.Bson.Serialization.Attributes;namespace AspMongoApi.Models;public class Student {[BsonId][BsonRepresentation(BsonType.ObjectId)]public string? Id { get; set; }public string? FirstName { get; set; }public string? LastName { get; set; }[BsonElement("School")]public string? Department { get; set; }}
In the preceding class, the Id property:
- Is required for mapping the Common Language Runtime (CLR) object to the MongoDB collection.
- Is annotated with [BsonId] to designate this property as the document's primary key.
- Is annotated with [BsonRepresentation(BsonType.ObjectId)] to allow passing the parameter as type string instead of an ObjectId structure. Mongo handles the conversion from string to ObjectId.
The Department property is annotated with the [BsonElement] attribute. The attribute's value of School represents the property name in the MongoDB collection.
Add the following to appsettings.json:
"StudentDbSettings": {"CollectionName": "Students","ConnectionString": "mongodb://localhost:27777","DatabaseName": "school-db"},
The entire contents of appsettings.json will look like this:
{"StudentDbSettings": {"CollectionName": "Students","ConnectionString": "mongodb://localhost:27777","DatabaseName": "school-db"},"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": "*"}
Add StudentDbSettings.cs to the Models folder with this code:
namespace AspMongoApi.Models;public class StudentsDbSettings {public string ConnectionString { get; set; } = null!;public string DatabaseName { get; set; } = null!;public string CollectionName { get; set; } = null!;}
The above StudentDbSettings class is used to store the appsettings.json file's StudentDbSettings property values. The JSON and C# property names are named identically to simplify the mapping process.
Add the following code to Program.cs before "var app = builder.Build();" :
builder.Services.Configure<StudentsDbSettings>(builder.Configuration.GetSection("StudentDbSettings"));
In the above code, the configuration instance to which the appsettings.json file's StudentDatabaseSettings section binds is registered in the Dependency Injection (DI) container.
Create a folder named Services and add to it a file named StudentService.cs with the following code:
namespace AspMongoApi.Services;public class StudentsService {private readonly IMongoCollection<Student> _studentsCollection;public StudentsService(IOptions<StudentsDbSettings> studentsDatabaseSettings) {var mongoClient = new MongoClient(studentsDatabaseSettings.Value.ConnectionString);var mongoDatabase = mongoClient.GetDatabase(studentsDatabaseSettings.Value.DatabaseName);_studentsCollection = mongoDatabase.GetCollection<Student>(studentsDatabaseSettings.Value.CollectionName);}public async Task<List<Student>> GetAsync() =>await _studentsCollection.Find(_ => true).ToListAsync();public async Task<Student?> GetAsync(string id) =>await _studentsCollection.Find(x => x.Id == id).FirstOrDefaultAsync();public async Task CreateAsync(Student newStudent) =>await _studentsCollection.InsertOneAsync(newStudent);public async Task UpdateAsync(string id, Student updatedStudent) =>await _studentsCollection.ReplaceOneAsync(x => x.Id == id, updatedStudent);public async Task RemoveAsync(string id) =>await _studentsCollection.DeleteOneAsync(x => x.Id == id);}
In the above code, an StudentsDbSettings instance is retrieved from Dependency Injection via constructor injection. Also, the above class knows how to connect to the MongoDB server and use the available driver methods to retrieve, insert, update and delete data.
Register the StudentService class with DI to support constructor injection. Add the following to Program.cs before "var app = builder.Build();" :
builder.Services.AddSingleton<StudentsService>();
Add the following code to Program.cs right before the "app.Run()l" statement:
app.MapGet("/students", async (StudentsService studentsService) => {
var students = await studentsService.GetAsync();
return students;
});
app.MapGet("/students/{id}", async (StudentsService studentsService, string id) => {
var student = await studentsService.GetAsync(id);
return student is null ? Results.NotFound() : Results.Ok(student);
});
app.MapPost("/students", async (StudentsService studentsService, Student student) => {
await studentsService.CreateAsync(student);
return student;
});
app.MapPut("/students/{id}", async (StudentsService studentsService, string id, Student student) => {
await studentsService.UpdateAsync(id, student);
return student;
});
app.MapDelete("/students/{id}", async (StudentsService studentsService, string id) => {
await studentsService.RemoveAsync(id);
return Results.Ok();
});
- Use the StudentService class to perform CRUD operations.
- Contains action methods to support GET, POST, PUT, and DELETE HTTP requests.
Running the application
Start the application by executing the this command from a terminal windows at the root of the application:
dotnet watch
Test the API with the Swagger interface that is available in your browser:
You can also view the data by pointing your browser to https://localhost:????/api/Students. This is the expected output:
Go ahead and test the other API endpoints for POST, PUT and DELETE using your favourite tool like Postman or curl. It should all work.
Cleanup
To stop & remove the MongoDB docker container, enter the following from any terminal window on your computer:
docker rm -f mgo
I hope you learned something new in this tutorial. Until next time, happy coding.
No comments:
Post a Comment