Archives 02/16/2022

Goal – Model-View-Controller

In the context of REST APIs, the MVC pattern aims to streamline the process of managing an entity by breaking it down into three separate, interacting components. Rather than struggling with large, bloated blocks of code that are hard to test, developers work with smaller units that enhance maintainability and promote efficient testing. This compartmentalization results in small, manageable pieces of functionality that are simpler to maintain and test.

Design

MVC divides the application into three distinct parts, where each has a single responsibility:

  • Model: The model represents the data and business logic we are modeling.
  • View: The view represents what the user sees. In the context of REST APIs, that usually is a serialized data structure.
  • Controller: The controller represents a key component of MVC. It orchestrates the flow between the client request and the server response. The primary role of the controller is to act as an HTTP bridge. Essentially, the controller facilitates the communication in and out of the system.

The code of a controller should remain minimalistic and not contain complex logic, serving as a thin layer between the clients and the domain.

We explore alternative points of view in Chapter 14, Layering and Clean Architecture.

Here is a diagram that represents the MVC flow of a REST API:

 Figure 6.1: Workflow of a REST API using MVCFigure 6.1: Workflow of a REST API using MVC 

In the preceding diagram, we send the model directly to the client. In most scenarios, this is not ideal. We generally prefer sending only the necessary data portion, formatted according to our requirements. We can design robust API contracts by leveraging the Data Transfer Object (DTO) pattern to achieve that. But before we delve into that, let’s first explore the basics of ASP.NET Core MVC.

Anatomy of ASP.NET Core web APIs

There are many ways to create a REST API project in .NET, including the dotnet new webapi CLI command, also available from Visual Studio’s UI. Next, we explore a few pieces of the MVC framework, starting with the entry point.

The entry point

The first piece is the entry point: the Program.cs file. Since .NET 6, there is no more Startup class by default, and the compiler autogenerates the Program class. As explored in the previous chapter, using the minimal hosting model leads to a simplified Program.cs file with less boilerplate code.Here is an example:

using Shared;
using System.Text.Json.Serialization;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCustomerRepository();
builder.Services
    .AddControllers()
    .AddJsonOptions(options => options
        .JsonSerializerOptions
        .Converters
        .Add(new JsonStringEnumConverter())
    )
;
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseDarkSwaggerUI();
}
app.MapControllers();
app.InitializeSharedDataStore();
app.Run();

In the preceding Program.cs file, the highlighted lines identify the minimum code required to enable ASP.NET Core MVC. The rest is very similar to the Minimal APIs code.