ASP.NET Core 6: The Minimal APIs

In this article, we will the implementation of Minimal APIs. As we all know that we have WEB APIs provided on .NET Framework and then ASP.NET Core eco-systems. But one common thing for the API implementation is that all these were implemented as Controller APIs, We need to create a Controller class that has the ApiController attribute applied and this is derived from the ControllerBase class. Once the controller is added, we add the HTTP Action method in it so that these will be executed based on HTTP requests. Although the approach of creating a controller class is great e.g. in the case of security, versioning, etc. But what if we need simple APIs e.g. creating Microservices in a simpler way. In this case, the API code must be easy and focused on the needs. The Minimal APIs provided in ASP.NET Core 6 are the best approach. 

The overall idea of creating Minimal API is that they avoid the code of creating a Controller class instead the HTTP requests are directly mapped with the implementation by defining APIs UR's. This makes implementation simple.  

Minimal APIs are articulated to create HTTP APIs with minimal dependencies. They are suitable for microservices development and apps that want to include only the minimum files, features, and dependencies in ASP.NET Core.          

Now let's see an implementation. I have implemented the Minimal API using Visual Studio 2022 for Mac.

Step 1: Create a New ASP.NET Core API project and make sure that you uncheck the User controllers (uncheck to use minimal APIs) checkbox to create API as shown in figure 1



Figure 1: Creating minimal API

The project will be created without any controller in it.

Step 2: Since EntityFrameworkCore is used for Accessing the data from SQL Server Database, the EntotyFrameworkCore packages Microsoft.EntityFrameworkCore, Microsoft.EntityFrameworkCore.SqlServer, Microsoft.EntityFrameworkCore.Tools and Microsoft.EntityFrameworkCore.Design are added as shown in figure 2



Figure 3: Various packages added

Step 3: We need to generate Entities using the Database First approach, so run the command shown in Listing 1 to generate Entities (Please change the Server Name, database name, and credentials as per database details installed on your machine)

dotnet ef dbcontext scaffold "Data Source=[SERVER-NAME];Initial Catalog=UCompany;User Id=[USER-NAME];Password=[Password]" Microsoft.EntityFrameworkCore.SqlServer -o Models

Listing 1: Generating entities using database first approach

Please Note that I have Department and Employee tables, the script of creating tables is shown in Listing 2

CREATE TABLE [dbo].[Department](
	[DeptNo] [int] Primary Key,
	[DeptName] [varchar](200) NOT NULL,
	[Location] [varchar](100) NOT NULL,
	[Capacity] [int] NOT NULL
)  

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Employee](
	[EmpNo] [int] NOT NULL,
	[EmpName] [varchar](400) NOT NULL,
	[Designation] [varchar](100) NOT NULL,
	[Salary] [int] NOT NULL,
	[DeptNo] [int] NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Employee] ADD PRIMARY KEY CLUSTERED 
(
	[EmpNo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, 
IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Employee]  WITH CHECK ADD FOREIGN KEY([DeptNo])
REFERENCES [dbo].[Department] ([DeptNo])
GO


Listing 2: Table Creation Script  

Step 4: Modify the default code generated for Program.cs using the code as shown in Listing 3

using System;


var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<UCompanyContext>(options=>options.UseSqlServer(builder.Configuration.GetConnectionString("AppConnection")));


var app = builder.Build();
// URLs bound to HTTP Server from Where API is accessible
app.Urls.Add("http://localhost:3000");
app.Urls.Add("http://localhost:4000");

// Get Request

app.MapGet("/api/departments",async (UCompanyContext context) => {
    var records = await context.Departments.ToListAsync();
    return Results.Ok(records);
});

// Post Request

app.MapPost("/api/departments", async (Department dept, UCompanyContext context) => {
    await context.AddAsync(dept);
    await context.SaveChangesAsync();
    return Results.Ok("Record Created Successfully");
});

// Put Request
app.MapPut("/api/departments/{id}", async (int id, Department dept, UCompanyContext context) => {
    var deptToUpdate = await context.Departments.FindAsync(id);
    if (deptToUpdate == null)
        return Results.NotFound("Record to Update is not Found");
    else
    {
        deptToUpdate.DeptName = dept.DeptName;
        deptToUpdate.Location = dept.Location;
        deptToUpdate.Capacity = dept.Capacity;
        await context.SaveChangesAsync();
        return Results.Ok("Record Updated Successfully");
    }
});
// Delete Request
app.MapDelete("/api/departments/{id}", async (int id, UCompanyContext context) => {
    var dept = await context.Departments.FindAsync(id);
    if (dept == null)
        return Results.NotFound("Record to Delete is not Found");
    context.Remove<Department>(dept);
    await context.SaveChangesAsync();
    return Results.Ok("Record Deleted Successfully");
});


app.Run();

 


Listing 3: The Program.cs with Minimal API Code

The code in Listing 3 shows that the WebApplication class is having extension methods such as MapGet(), MapPost(), MapPut(), and MapDelete() to map incoming HTML requests on the URL with the anonymous function passed to these methods as a second parameter. The first parameter to these methods is the pattern that will be used by the HTTP request to call API. Another important point here is that the Urls property of WebApplication class allows setting custom URLs on which the API can be exposed. In our case ports, 3000 and 4000 are set for access HTTP requests.

Run the Project and use the Postman to make calls to the Minimal API. We can successfully access APIs on the following URLs

http://localhost:3000/api/departments

Conclusion: Minimal APIs are useful to implement apps like Microservices with simple and focused code. 

The code for this article can be downloaded from this link.


    

       




Popular posts from this blog

ASP.NET Core 6: Adding Custom Middleware and Logging the Error Message in Database

ASP.NET Core 6: Downloading Files from the Server

ASP.NET Core 6: Using Role Based Security for ASP.NET Core 6 WEB API