Follow us

.Net 6 - Minimal API

 

Minimal API introduced with .net 6 and this is very good in sense:

  • Best suited for micro services to put your related endpoints in project.
  • This is light weight compare to .net core standard(MVC) API pattern and it contains less no. of files like do not need to create controllers.
  • Less no. of lines of codes to write to create endpoint.
  • Single file API, to put all endpoints related to that project with program.cs file.
  • You should be able to get all the benefits and features similar to .net core standard(MVC) pattern API like:
    • Creating different methods GET, POST, PUT etc..
    • Defining routes for API.
    • Sending query string to API.
    • Sending headers to API.
    • Dependency injection like .net core (injecting objects).
    • Async, Await call.
    • Authentication/Authorization.
    • Support other packages which you had used earlier like Fluent validation to create validation for your API.
    • Etc..  We will see all these in below demo.

 

Demo:

 

While you create ".Net core web api" in visual studio, there is checkbox option for minimal API, so you need to unselect that, otherwise it will create normal MVC pattern for your API. Refer below screenshot:

Additional information 
ASP.NET Core Web API 
Linux 
Framework (D 
.NET 6.0 (Long-term support) 
Authentication type C) 
None 
@ Configure for HTTPS O 
Enable Docker 
Docker OS 
Linux 
Use controllers (uncheck to use minimal APIs) 
Enable OpenAPI suppot C) 
ma c OS 
Windows 
Cloud 
Service 
Web

Once you created, by default it give you weather forecast related APIs, which you get even in case of .net core standard API. But all those action methods are inside program.cs file and if you see the solution explorer, it just having few files and not controllers at all and it also by default provide you swager configuration. So when you run your application, it will open up swagger, where you can use the default APIs available. Refer below screenshot:

Note: Mainly here we use "MapGet", "MapPost", "MapPut" etc. methods to setup respective APIs as on need.

Continue • 
Live re 
ADMI 
•rogram.cs• x 
UebAppIicatio„.Test: Overview 
WebApplication1APlEmpty.Net6Test 
ThrQd: 
Weath east 
Swagger UI 
Swagger 
localhost:7176/swagger/i n d ex. ht... 
ed E 00k M 
Select a 
WebAppIicationIAPIEmpty 
definition 
Rebding list 
18 
var Duiloer : WeOAøptication.Createeuitder(args); 
// Add to the container. 
// about at 
der _ _ AddEndpoin ; 
Services _ AddS.agger-Gen() ; 
— builder. Build(); 
var r — 
/ / HTTP pipeline. 
Solution 
SolutiM1 Explorer (Ctrl") 
External Sources 
I AP 
C+ Connected Services 
DepmderÆlæ 
Properties 
cz Program.cs 
(app _ IsDeve10JÆt()) 
app _ usa%aggoro 
app. LJ5eSuaqgerUIO ; 
16 app. us ) ; 
181 vu Aies — 
281 Sapp. NagGetC 
'nattier-forecast " , 
var forecast 
= EnuneraDIe.Range(I, 5) .SeIect(index 
Nou MdD.ays(index) 
Shared . Length)) 
. ToArray(); 
return forecast; 
WebAppIication1APlEmpty 
1.0 OAS' 
httDS4,'IocaI host.' json 
WebApplication1APlEmpty.Net6Test 
GET 
o recast

 

Demo 1: GET, POST, Async, Query String Test

 

  • Created below "UserManager.cs" file where I have created "User" as record struct type with Id and Name property.
  • With UserManager class, I have created:
    • "GetUsers() to get list of dummy users".
    • "GetUser() with Id input to filter user and get specific user".
    • "AddUser() with User record type post input to add user".
    • "GetUsersAsyncTest() to test async call from minimal API".

 

:cr.cs 
Program.cs 
UserManager.cs -E X • 
31 i cation IAPIEmpty.Net6Test 
Ol$WebAppIicationIAPIEmpty.Net6Test.UserManager • 
namespace WebApp11cat10nIAPIE•pty. Net6Test; 
public record struct User(int Id, string Name); 
—public class Usermanager 
public GetUsers() { return GetDummyUsers(); } 
public User GetUser(int id) 
var dummyUsers 
GetDumnyUsersO ; 
var user = dummyUsers. x :uzer 
x.ld= 
return user ; 
public int AddUser(Llser user) { 
var dummyUsers 
GetDummyUsers O ; 
GetUsersO 
"User already exists with same id. 
Solution Explorer 
Search Solution Explorer (Ctrl+,•) 
Solution 'WebA lication I API Em .Net6T 
C$-, Connected Services 
88 Dependencies 
Properties 
appsettingsjson 
Ctt Program.cs 
co UserVaIidator.cs 
var existingUser = dunmyusers. x 
if nul! existinglJser.Id > 
dummyUsers. Adätuserji 
return user. Id; 
public async GetUsersAsyncTest() 
private GetDum•yLlsersO { 
x. Id = user.ld); 
e) { throw new 
{ return await 
return new { new 
{ I, Name 
"User I" } , 
Exception( 
neu 
{ Id 
2 , Name 
"User 2" } l;

 

  • With "Program.cs" I have used above "UserManager" and created endpoints.
    • First API I created Get type to check heartbeat of my application.
    • Second API for getting list of users.
    • Third API to get specific user as per Id which I am sending as query string and if you see, I have used two different way to send query string.
    • Fourth API is post type to add user, where I sending "User" record struct as request body and in result will get new user id with http status code to OK(200).
    • Fifth API is to see, how we can use async and await with minimal API.

 

atcr.cs 
"name": "User 4"} 
UserManager.cs 
Program.cs -a X 
ppIicationIAPIEmpty.Net6Test 
using WebAppLicationIAPIE•pty. Net6Test; 
var builder = WebAppIication . ; 
// Add services to the container. // Learn more about configuring Swagger/OpenAPI at 
builder. Services . AddEndpointsApiExpIorer() ; 
builder. Services . ; 
builder. Build() ; 
var app 
: webAppLica±izn 
// Configure the kTTP request pipeline. 
(app . Environment .1sDeveIop•entO) {l 
app . UseSuagger() 
app . UseSuaggerUIO ; 
var 
us nager 
new UserManagerO; 
/CheckHeaRBeat", 
app. MapGet( 
app. MapGet( 
app . NapGet( 
app .MapGet( " 
app. MapPost( 
app.MapGet( " 
app . Runt) ; 
O "I a. alive!"); //Ur1: 
/GetUsers" , 
0 userManager.GetUsers()); //UrL: 1/1 oral hnst 76/GatIIszrs 
/GetUser/ , 
(int userld) userNanager.GetUser(userId)); //UrI: httDS' 
(int userld) userManager.GetUser(userId)); //LlrI: httos: 
"/AddLlser" , 
(User user) //UrL: httos://lnralhnst 76/AddIIsar, request post body: 
/GetUsersAsyncTest" , 
async O await userManager.GetUsersAsyncTestO); //LlrI: '7176/GptIJsprsAsynrTpst

 

Demo 2: DI (dependency injection): with demo 1, if you see, I have created "UserManager" class object myself and then used that object to call respective methods inside respective API. Now instead of creating self object, I want to use/setup DI with minimal API, how we do in .net core startup.cs file to inject class and then as per scope defined, it create object available in constructor of that class. So,

  • First you have to configure the respective class with scope. With below example, I am creating singleton object for my UserManager class.
  • Then with API method, you have to use "[FromServices] attribute for your class, so that while using that class object it will pull the object allocation from the services injection.

 

atcr.cs 
UserManager.cs 
Program.cs -a X 
ppIicationIAPIEmpty.Net6Test 
7 Fusing WebAppLicationIAPIE•pty. Net6Test; 
using Microsoft . AspNetCore. Mvc; //GetUsersDITest 
var builder = WebAppIication . CreateBuiIder(args); 
// Add services to the container. 
// Learn •ore about configuring Swagger/OpenAPI at httDv . ms/asonetrnre/%ashhnrklz 
builder. Services . AddEndpointsApiExpIorer() ; 
builder. Services . 
// Added as ser.'ice(DI -For UserManager class) //GetUsersDITest 
builder. Services. AddSing ; 
builder. Build() ; 
var app 
// Configure the kTTP request pipeline. 
i3 (app. Environment .1sDeveIop•entO) 
app . UseSuagger() 
app . UseSuaggerUIO ; 
app.MapGet( " 
/GetUsersDITest" , 
app. Run O ; 
( [FronServicesJ Usermanager _userNanager.GetUsers O) ; 
//Ur1: 
httos: / / I m-al host 7176/GptIJsprsDITpst

 

Demo 3: With this demo, I want to receive/capture header input sent from the consumer and to do that you have to use "[FromHeader] attribute".

  • With below API, I am creating variable "AuthenticationToken" which will be send into header while calling this API.

 

UserManager.cs 
licationIAPIEmpty.Net6Test 
Program.cs -a X 
—using Microsoft . AspNetCore. Mvc; //keaderRequestTest 
using WebAppIicationIAPIE•pty. Net6Test; 
var builder = WebAppIication . ; 
// Add services to the container. 
// Learn •ore about configuring Swagger/OpenAPI at httDv 
builder. Services . AddEndpointsApiExpIorer() ; 
builder. Services . ; 
builder. Build O ; 
var app 
// Configure the kTTP request pipeline. 
(app . Environment { 
app . UseSuagger() 
app . UseSwaggerUIO ; 
app. MapGet( " 
/HeaderRequestTest" , 
"AuthenticationToken")] string authenticationToken) 
return $ "Result — AuthenticationToken: {authenticationToken}" 
D; //UrI: httos://lnralhnst + pass "AuthenticationToken" into header while requesting this endpoint 
app. Run O ;

 

Demo 4: Add JWT Authentication/Authorization with minimal API.

  • With below example, marked in "Yellow" color, where I have enabled "JWT" token for my endpoints.
    • To enable authentication with each individual API, we can use either "[Authorize] attribute" or "RequireAuthorization() method", refer below marked in yellow both the examples.
    • To enable AllowAnonymous, you have to use either "[AllowAnonymous] attribute" or "AllowAnonymous() method", refer below marked in yellow both the examples.
  • With below example marked in "Turquoise" color, where I have enabled/configured header input for JWT token on swagger.
  • Also to use JWT token, you have to install JwtBearer package, refer below screenshot:

NuGet: WebAp.. .pty. Net6Test 
Browse 
Installed 
jwtbearer 
x 
Updates 
Program.cs 
CD Include prerelease 
NuGet Package Manager: WebApplication1APlEmpty.Net6Test 
Package source: 
Microsoft.AspNetCore.Authenticatc?o nuget.org 
Microsoft.AspNetCore.Authentication.JwtBearer by Microsoft, 151M downloads 
ASP .NET Core middleware that enables an application to receive an OpenlD Connect bearer token. 
Volo.Abp.AspNetCore.Authentication.JwtBearer by Volo.Abp.AspNetCore.Authentication.Jwt8earer, 354K dom 
Package Description 
6.0.o 
Version: Latest stable 6.0.0 
Options 
Install

 

 

using Microsoft.AspNetCore.Authentication.JwtBearer; //JWTToken for auth

using Microsoft.AspNetCore.Authorization;

using Microsoft.OpenApi.Models; //AuthTest

 

var builder = WebApplication.CreateBuilder(args);

 

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle

builder.Services.AddEndpointsApiExplorer();

//builder.Services.AddSwaggerGen();

//Add swagger to have Bearer token option available for header input

builder.Services.AddSwaggerGen(config => {

                                   config.AddSecurityDefinition("Bearer",

                                       new OpenApiSecurityScheme {

                                                                     Description = "JWT header token using 'bearer' scheme",

                                                                     Name = "BearerToken", //Bearer

                                                                     In = ParameterLocation.Header,

                                                                     Type = SecuritySchemeType.ApiKey

                                                                 });

                                   config.AddSecurityRequirement(new OpenApiSecurityRequirement {

                                                                                                    {

                                                                                                        new OpenApiSecurityScheme

                                                                                                        {

                                                                                                          Reference = new OpenApiReference {

                                                                                                              Id = "Bearer", Type = ReferenceType.SecurityScheme

                                                                                                          }

                                                                                                        },

                                                                                                        new List<string>()

                                                                                                    }

                                                                                                });

                               });

 

//AuthTest

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer();

//This is require to enable authorization for all the endpoints, instead of using [Authorize] attribute to each individual endpoint

builder.Services.AddAuthorization(options => {

                                      options.DefaultPolicy = new AuthorizationPolicyBuilder().

                                                              AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).

                                                              RequireAuthenticatedUser().Build();

                                  });

 

var app = builder.Build();

 

// Configure the HTTP request pipeline.

if (app.Environment.IsDevelopment()) {

    app.UseSwagger();

    app.UseSwaggerUI();

}

 

app.UseAuthorization();

app.UseAuthentication();

 

app.MapGet("/AuthTest-AllowAnonymous", [AllowAnonymous] () => "This endpoint is set for AllowAnonymous."); //Url: https://localhost:7176/AuthTest-AllowAnonymous

app.MapGet("/AuthTest-AllowAnonymous-Option2", () => "This endpoint is set for AllowAnonymous.").AllowAnonymous(); //Url: https://localhost:7176/AuthTest-AllowAnonymous

 

app.MapGet("/AuthTest-Authorize", [Authorize] () => "This endpoint is set for AllowAnonymous."); //Url: https://localhost:7176/AuthTest-Authorize

app.MapGet("/AuthTest-Authorize-Option2", () => "This endpoint is set for AllowAnonymous.").RequireAuthorization(); //Url: https://localhost:7176/AuthTest-Authorize-Option2

 

app.Run();

 

Result of above code:

C localhost:7176/swagger"ndex.html 
n 
SavedBookMarks 
o 
Swagger 
WebApplication1APlEmpty.Net6Test 
Available authorizations 
Bearer (apiKey) 
JM using 
In: 
WebApplication1APlEmpty.Ne 
/ uthTest-AIIowAnonymoL 
/ Auth Test Optio 
uthTest-Authoriz 
uthTest-Authorize-Option: 
Selecta definition 
WebAppIication I APIEmpty. NetSTest VI

 

 

 

Categories/Tags: minimal api~.net 6

Recent Articles

1

AWS Saving Plan - Cost optimization tips

2
3

AWS RDS Key Concepts & Why you should use it?

4
5

Open-Search/Kibana - Multi Tenancy Setup

See All Articles