Esercizio: personalizzare e ampliare la documentazione di OpenAPI con commenti e annotazioni XML
In questo esercizio si arricchisce la documentazione che uno sviluppatore vede sull'API aggiungendo commenti e annotazioni al codice. Per prima cosa analizzare ciò che viene specificato per impostazione predefinita da Swagger UI.
Per esaminare la definizione OpenAPI dell'endpoint dell'API nell'interfaccia utente di Swagger, passare a
http://localhost:5000/swagger
nel browser. Verrà visualizzato un output simile al seguente quando si seleziona il metodo Get.Swagger UI offre alcune informazioni utili sull'API. Illustra i metodi che è possibile chiamare (nel semplice caso di esempio usato in questa unità, un metodo chiamato PriceFrame). È possibile notare che si tratta di un'operazione HTTP Get che accetta due parametri obbligatori denominati Height e Width. Per visualizzare la chiamata API in azione, è possibile selezionare Prova, immettere i valori per Altezza e Larghezza e selezionare Esegui.
Gli utenti dell'API non dispongono ancora di informazioni sufficienti per conoscere le limitazioni del metodo PriceFrame . È possibile aiutarli offrendo informazioni più dettagliate tramite i commenti XML.
Aggiungere commenti in formato XML all'API
Tornare all'istanza di Visual Studio Code usata per l'ultimo esercizio.
Se l'API Web è ancora in esecuzione nell'ultimo esercizio, premere CTRL+c in Windows o cmd+c su Mac per arrestarla.
Per attivare la documentazione XML nel progetto, aggiornare il file di progetto PrintFramerAPI.csproj e aggiungere il tag
GenerateDocumentationFile
al<PropertyGroup>
esistente, quindi impostarlo sutrue
.<PropertyGroup> <TargetFramework>net7.0</TargetFramework> <GenerateDocumentationFile>true</GenerateDocumentationFile> <NoWarn>$(NoWarn);1591</NoWarn> </PropertyGroup>
Aggiungere le istruzioni using seguenti nel file Startup.cs.
using System.Reflection; using System.IO;
In Startup.cs indicare a Swashbuckle di usare la documentazione XML aggiornando la chiamata a
AddSwaggerGen()
inConfigureServices
.public void ConfigureServices(IServiceCollection services) { services.AddControllers(); // Register the Swagger generator, defining 1 or more Swagger documents services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "PrintFramer API", Description = "Calculates the cost of a picture frame based on its dimensions.", TermsOfService = new Uri("https://go.microsoft.com/fwlink/?LinkID=206977"), Contact = new OpenApiContact { Name = "Your name", Email = string.Empty, Url = new Uri("https://learn.microsoft.com/training") } }); // Set the comments path for the Swagger JSON and UI. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); }); }
Nel codice precedente, la reflection determina il nome del file XML per caricare i commenti.
Nella cartella Controllers aprire PriceFrameController.cs. Aggiungere il blocco di commento XML seguente sopra l'attributo HttpGet del
GetPrice
metodo . Se si aggiungono commenti con barra tripla a un'azione si migliora Swagger UI aggiungendo la descrizione all'intestazione della sezione./// <summary> /// Returns the price of a frame based on its dimensions. /// </summary> /// <param name="Height">The height of the frame.</param> /// <param name="Width">The width of the frame.</param> /// <returns>The price, in dollars, of the picture frame.</returns> /// <remarks> The API returns 'not valid' if the total length of frame material needed (the perimeter of the frame) is less than 20 inches and greater than 1000 inches.</remarks> [HttpGet("{Height}/{Width}")] public string GetPrice(string Height, string Width) { string result; result = CalculatePrice(Double.Parse(Height), Double.Parse(Width)); return $"The cost of a {Height}x{Width} frame is ${result}"; }
Per salvare tutte le modifiche e assicurarsi che la compilazione sia eseguita in locale, eseguire il comando seguente nella finestra del terminale di Visual Studio Code.
dotnet build
Per visualizzare le modifiche, eseguire l'applicazione ASP.NET in locale immettendo quanto segue nella finestra del terminale Visual Studio Code:
dotnet run
Esaminare nuovamente l'interfaccia utente di Swagger all'indirizzo
http://localhost:5000/swagger
e osservare le informazioni aggiunte specificate dai commenti XML alla documentazione OpenAPI.
Aggiungere annotazioni dei dati all'API
Per consentire a Swagger di migliorare la documentazione OpenAPI, è possibile usare gli attributi dello spazio dei nomi Microsoft.AspNetCore.Mvc
.
Se l'API Web è ancora in esecuzione nell'ultimo esercizio, premere CTRL+c in Windows o cmd+c su Mac per arrestarla.
Per indicare che l'API
GetPrice
supporta una risposta text/plain per il tipo di contenuto, nel controller dell'API PriceFrameController.cs aggiungere un attributo[Produces("text/plain")]
sopra la definizioneGetPrice
.[HttpGet("{Height}/{Width}")] [Produces("text/plain")]
L'elenco a discesa del tipo di contenuto della risposta seleziona questo tipo di contenuto come predefinito per le azioni GET del controller.
Aggiungere annotazioni Swashbuckle all'API
Finora, l'API restituisce il codice di stato 200 quando può calcolare un prezzo per le dimensioni del frame specificate. Nella descrizione del GetPrice
metodo prendere nota del caso in cui non è possibile calcolare un prezzo.
Un modo più efficace per illustrare agli sviluppatori i tipi di risposta e i codici di errore è usare i commenti XML e le annotazioni dei dati seguenti. Gli strumenti Swashbuckle e Swagger usano questi valori per generare chiaramente una descrizione OpenAPI dei codici di risposta HTTP previsti.
Aggiornare anche il costruttore del filtro verbo HTTP per includere la Name
proprietà e includere il valore OpenAPI operationId
.
Aggiungere l'istruzione using seguente al file PriceFrameController.cs .
using Microsoft.AspNetCore.Http;
In PriceFrameController.cs sostituire
GetPrice
con il codice e il commento seguenti./// <summary> /// Returns the price of a frame based on its dimensions. /// </summary> /// <param name="Height">The height of the frame.</param> /// <param name="Width">The width of the frame.</param> /// <returns>The price, in dollars, of the picture frame.</returns> /// <remarks> /// Sample request: /// /// Get /api/priceframe/5/10 /// /// </remarks> /// <response code="200">Returns the cost of the frame in dollars.</response> /// <response code="400">If the amount of frame material needed is less than 20 inches or greater than 1000 inches.</response> [HttpGet("{Height}/{Width}", Name=nameof(GetPrice))] [Produces("text/plain")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public ActionResult<string> GetPrice(string Height, string Width) { string result; result = CalculatePrice(Double.Parse(Height), Double.Parse(Width)); if (result == "not valid") { return BadRequest(result); } else { return Ok($"The cost of a {Height}x{Width} frame is ${result}"); } }
Questo codice apporta le modifiche seguenti:
- Il metodo usa i metodi
BadRequest()
eOk()
per creare rispettivamente lo stato BadRequest (400) e lo stato Ok, passando il risultato della stringa alla risposta. - I commenti XML descrivono ogni codice di stato che questo metodo può restituire.
- L'attributo HttpGet include una
Name
proprietà per generare il parametro OpenAPIoperationId
. - Gli attributi ProducesResponseType elencano le diverse risposte che l'azione può restituire. Questi attributi vengono combinati con i commenti XML, come descritto in precedenza, per includere descrizioni comprensibili a un lettore umano in ogni risposta generata in Swagger.
- Il metodo usa i metodi
Ricompilare l'API Web con il comando seguente:
dotnet build
Eseguire l'applicazione ASP.NET con il comando seguente:
dotnet run
Esaminare nuovamente l'interfaccia utente di Swagger all'indirizzo
http://localhost:5000/swagger
e osservare le informazioni aggiunte specificate dalle annotazioni. Nell'immagine seguente viene visualizzata l'interfaccia utente di Swagger finale per l'API.
In questo esercizio sono state arricchite le informazioni ricevute da uno sviluppatore sull'API, rendendo molto più semplice l'uso.