.NET 6 minimal web API è un nuovo modello per creare delle
API molto veloci con poche righe di codice, avendo a disposizione tutta la potenza di
.NET 6.
Verifica
Come prima cosa va verificato se è installato
.NET 6
deve comparire la versione 6.x.xxx
3.1.420 [C:\Program Files\dotnet\sdk]
5.0.408 [C:\Program Files\dotnet\sdk]
6.0.106 [C:\Program Files\dotnet\sdk]
6.0.300 [C:\Program Files\dotnet\sdk]
6.0.301 [C:\Program Files\dotnet\sdk]
Creazione progetto
Il progetto può essere creato da linea di comando con
dotnet new web ed editato con
Visual Studio Code o direttamente in
Visual Studiomkdir Sgart.Net.MinimalAPI
cd Sgart.Net.MinimalAPI
dotnet new web
code .
da come output
Creazione del modello "ASP.NET Core Empty" completata.
Elaborazione post-creazione delle azioni in corso...
Esecuzione di 'dotnet restore ' in D:\PROJECTS\...\Sgart.Net.MinimalAPI\Sgart.Net.MinimalAPI.csproj...
Individuazione dei progetti da ripristinare...
D:\PROJECTS\...\Sgart.Net.MinimalAPI\Sgart.Net.MinimalAPI.csproj ripristinato (in 141 ms).
Il ripristino è riuscito.
Il parametro corretto per un progetto minimal web API è web e non webapi.
La struttura del progetto è questa:
- Properties
- launchSettings.json
- appsettings.Development.json
- appsettings.json
- Program.cs
- Sgart.Net.MinimalAPI.csproj
dove tutto il codice risiede in
Program.cs e sono solo
4 lineevar builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Sgart.it ciao");
app.Run();
Non esiste più il file Startup.cs
Esecuzione
lo si può eseguire con il comando
il parametro watch manda in esecuzione il codice, rimane in attesa di cambiamenti al sorgente e riavvia la compilazione
Una volta chiamata l'API, verrà visualizzata la scritta
Sgart.it ciao.
RootAggiunta API
Ovviamente si possono aggiungere altre API tramite il metodo
MapGet, ad esempio per calcolare la
radice quadrata di un numero
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Sgart.it ciao");
app.MapGet("/sqrt/{num:int}", (int num) => Math.Sqrt(num));
app.Run();
che può essere invocata con
https://localhost:7195/sqrt/5
Radice quadrataI metodi
HTTP disponibili sono:
- MapGet => per restituire dei dati
- MapPost => per inviare dei dati che creano una risorsa
- MapPut => per inviare dei dati che modificano una risorsa
- MapDelete => per rimuovere una rosorsa
Posso usare il metodo in
POST per aggiungere una nuova API che
moltiplica (/mult) 2 numeri:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
...
app.MapPost("/mult", ([int num) => Math.Sqrt(num));
...
app.Run();
# record (C# 9) di supporto per i dati in ingresso
record MultInputDTO(int V1, int V2);
Attenzione se l'API aggiunta non viene trovata, nella console, dove è in esecuzione il comando dotnet watch, premere CTRL + R per riavviare.
Post415 Unsupported Media Type se si ottiene questo messaggio vuol dire che nell'header della richiesta manca content-type: application/json
Json
Per impostazione predefinita la
serializzazione degli oggetti è sempre e solo in
Json camelCaseAd esempio se aggiungo un metodo
/tan che ritorna un oggetto
...
app.MapGet("/tan/{num:int}", (int num) => new
{
result = Math.Tan(num)
});
...
il risultato è questo
Risultato in JSONNLog
Una delle funzionalità principali di un programma è la capacita di "loggare" le sua attività.
Si tratta di una funzionalità
indispensabile per fare debug in produzione in caso di problemi.
Vediamo come aggiungere
NLog.
Per prima cosa aggiungiamo il pacchetto
NuGet dotnet add package NLog.Web.AspNetCore --version 5.0.0 dotnet add package NLog.Web.AspNetCore --version 5.0.0
e poi lo inizializziamo
using NLog;
using NLog.Web;
// imposto NLog per leggere da appsettings.json
var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Debug("Sgart.it demo init");
try
{
var builder = WebApplication.CreateBuilder(args);
...
// Setup NLog for Dependency injection
builder.Logging.ClearProviders();
builder.Host.UseNLog();
var app = builder.Build();
...
app.Run();
}
catch (Exception exception)
{
// NLog: catch setup errors
logger.Error(exception, "Stopped program because of exception");
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
Da notare che la configurazione di NLog viene letta da appsettings.json (LoadConfigurationFromAppSettings).
Passo successivo, impostare la configurazione di NLog
{
"Logging": {
"LogLevel": {
"Default": "Trace",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"NLog": {
"throwConfigExceptions": true,
"autoReload": true,
"internalLogLevel": "Info",
"internalLogFile": "c:/logs/Sgart.Net.MinimalAPI/internal.log",
"targets": {
"log-console": {
"type": "Console"
},
"all-file": {
"type": "File",
"fileName": "c:/logs/Sgart.Net.MinimalAPI/all-${shortdate}.log",
"layout": "${longdate} ${uppercase:${level}}| ${message} | ${callsite} ${exception:format=tostring}"
},
"log-trace": {
"type": "Trace"
}
},
"rules": [
{
"logger": "*",
"minLevel": "Trace",
"writeTo": "log-console"
},
{
"logger": "*",
"minLevel": "Trace",
"writeTo": "all-file"
},
{
"logger": "*",
"minLevel": "Warn",
"writeTo": "log-trace"
}
]
}
}
una volta fatta ripartire l'applicazione i log si troveranno in
c:/logs/Sgart.Net.MinimalAPI.
Il log è configurato, posso usarlo dove voglio
app.MapGet("/sqrt/{num:int}", (int num) =>
{
double result = Math.Sqrt(num);
logger.Info($"sqrt({num}) = {result}");
return result;
});
che scriverà nel log
2022-07-09 22:43:02.0244 INFO| sqrt(5) = 2,23606797749979 | Program.<Main
Force https
Tutti i siti, per questioni di sicurezza
devono funzionare solo in
https, quindi meglio forzare il redirect
...
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
....
File statici
Se oltre all'API è richiesto il supporto di file
statici quali, immagini
CSS,
JavaScript, ecc..., deve essere abilitato il supporto con
UseStaticFiles...
app.UseHttpsRedirection();
app.UseStaticFiles();
....
Demo
La demo di questo esempio è presente su
GitHub Sgart.Net.MinimalAPI mentre una demo più estesa è disponibile a questo link
Demo Web application .Net 6 minimal api + EF Core 6 + Nlog + React 18 function & hooks / Bootstrap 5 + WebAP.
Vedi anche
Entity Framework con .NET 6 minimal web API.
Per approfondire
Creare app Web e servizi con ASP.NET Core, API minima e .NET 6.