Migliorare la documentazione Swagger di ASP.NET Core Web API
In un precedente script abbiamo visto come documentare un'applicazione ASP.NET Core Web API usando Swagger/OpenAPI (https://www.aspitalia.com/script/1301/Documentare-Web-API-Swagger-ASP.NET-Core-2.1.aspx). Usare questo accorgimento è essenziale perché agevola gli altri sviluppatori nell'integrare la loro applicazione con la nostra. Sebbene sia generata automaticamente, possiamo comunque intervenire per migliorare la qualità della documentazione in modo da aiutare ancora di più gli utilizzatori della nostra Web API.
Prendiamo ad esempio un'action come la seguente:
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
// GET api/products/search
[HttpGet, Route("search")]
public async Task<ActionResult<IEnumerable<Product>>> Search([Required] string term)
{
IEnumerable<Product> results = await productService.SearchAsync(term);
if (results.Any())
{
return Ok(results);
}
return NotFound();
}
}
Come si vede nel codice, si tratta di un'action per la ricerca di prodotti e può restituire vari tipi di risultato:
- Un elenco di oggetti Product con status code 200 se la ricerca va a buon fine;
- Una risposta con status code 404 (Not Found) se la ricerca non produce alcun risultato;
- Una risposta con status code 400 (Bad Request) generata implicitamente se il client vìola l'obbligatorietà del parametro term, data la presenza dell'attributo Required (vedere il precedente script https://www.aspitalia.com/script/1297/Validazione-Automatica-Parametri-Web-API-ASP.NET-Core-2.1.aspx);
Tuttavia, se osserviamo la documentazione Swagger che viene generata automaticamente, non troviamo alcuna traccia dei risultati con status code 400 e 404. Infatti, è presente solo il risultato con status code 200.

A partire da ASP.NET Core 2.2, Microsoft ha introdotto un analyzer per applicazioni Web API che evidenzia queste situazioni nel codice e che perciò ci incentiva a produrre una documentazione più precisa. Iniziamo installando l'analyzer come pacchetto NuGet lanciando il seguente comando:
dotnet add package Microsoft.AspNetCore.Mvc.Api.Analyzers
A questo punto, Visual Studio evidenzierà il problema e ci proporrà un code fix come mostrato nell'immagine seguente.

Se invece stiamo usando Visual Studio Code non possiamo sfruttare questo automatismo perché, per ora, gli analyzer non sono supportati (segui la relativa issue su GitHub https://github.com/OmniSharp/omnisharp-vscode/issues/43). Come si vede di seguito, ci verrà comunque evidenziato il problema alla compilazione con un avviso.

In ogni caso, possiamo pur sempre risolvere il problema decorando manualmente l'action con gli attributi ProducesResponseType per indicare gli status code previsti. Se abbiamo usato delle data annotation come Required, ricordiamoci anche di indicare lo status code 400 come si vede di seguito.
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[HttpGet, Route("search")]
public async Task<ActionResult<IEnumerable<Product>>> Search([Required] string term)
{
//...
}
A questo punto, la documentazione risulterà coerente con il comportamento della nostra action. Nella seguente immagine si vede infatti che ora sono elencati anche gli status code 400 e 404.

Il risultato per gli status code 4xx viene impostato su ProblemDetails, in accordo con lo standard RFC7807 (https://tools.ietf.org/html/rfc7807) che si propone di normare i messaggi di errore restituiti dalle Web API. Ecco un esempio di cosa riceverà il client quando si verifica un errore 400.
{
"errors": {
"term": [
"The term field is required."
]
},
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "0HLKHV24T50LG:00000004"
}
All'interno della risposta JSON, ASP.NET Core riporta ogni eventuale violazione delle data annotation come Required che abbiamo usato per validare il modello dati in ingresso.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzare l nesting nativo dei CSS
Aprire una finestra di dialogo per selezionare una directory in WPF e .NET 8
Esporre i propri servizi applicativi con Semantic Kernel e ASP.NET Web API
Evitare (o ridurre) il repo-jacking sulle GitHub Actions
Introduzione alle Container Queries
Sfruttare gli embedding e la ricerca vettoriale con Azure SQL Database
Cambiare la chiave di partizionamento di Azure Cosmos DB
Supportare la sessione affinity di Azure App Service con Application Gateway
Utilizzare un numero per gestire la concorrenza ottimistica con SQL Server ed Entity Framework
Paginare i risultati con QuickGrid in Blazor
Utilizzare il trigger SQL con le Azure Function
Inference di dati strutturati da testo con Semantic Kernel e ASP.NET Core Web API
I più letti di oggi
- Real Code Day 4.0: costruire applicazioni reali - Firenze
- Annunciato Silverlight 2.0
- Prima CTP per Portable Library Tools
- .NET Roadshow 2003 in compagnia di Dino Esposito
- Eventi gratuiti in 6 città italiane per Office System 2003 e .NET Framework
- Visual Studio Team System si espande con la nuova Database Professionals Edition
- Nuove API per Mono 1.2.4
- Community Days 2010: Entity Framework Code-First
- Visual Studio Code: costruire web app per Windows, Linux e MacOSX