.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

DOS / Batch file

dotnet --list-sdks
deve comparire la versione 6.x.xxx

Text

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 Studio

DOS / Batch file

mkdir Sgart.Net.MinimalAPI
cd Sgart.Net.MinimalAPI
dotnet new web
code .
da come output

Text

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 linee

C#: Program.cs

var 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

DOS / Batch file

dotnet watch
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.
Root
Root

Aggiunta API

Ovviamente si possono aggiungere altre API tramite il metodo MapGet, ad esempio per calcolare la radice quadrata di un numero

C#: Program.cs

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 quadrata
Radice quadrata

I 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:

C#: Program.cs

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.
Post
Post
415 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 camelCase

Ad esempio se aggiungo un metodo /tan che ritorna un oggetto

C#: Program.cs

...
app.MapGet("/tan/{num:int}", (int num) => new
{
    result = Math.Tan(num)
});
...
il risultato è questo
Risultato in JSON
Risultato in JSON

NLog

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

DOS / Batch file

dotnet add package NLog.Web.AspNetCore --version 5.0.0
e poi lo inizializziamo

C#: Program.cs

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

JSON: appsettings.json

{
  "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

C#: Program.cs

app.MapGet("/sqrt/{num:int}", (int num) =>
{
    double result = Math.Sqrt(num);

    logger.Info($"sqrt({num}) = {result}");

    return result;
});
che scriverà nel log

Text

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

C#: Program.cs

...
    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

C#: Program.cs

...
    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.
Tags:
.NET 65 C#235 .NET66 .NET Core26 JSON31
Potrebbe interessarti anche: