Swagger-Net - Documentazione dinamica
Con il Framework 4.8 , in un un contesto di WebApi, Swagger interviene generando una documentazione interattiva HTML che prende come sorgente i modelli dei dati e le loro descrizioni da codice sorgente.
Pagina del progetto: https://github.com/heldersepu/Swagger-Net
Ecco come procedere, avendo già creato un WebApi/Rest-Service:
- Manage NuGet packages e installare
Swagger-Net - È possibile testare subito runnando la soluzione alla pagina
/swagger(se non funziona qui sono cazzi tuoi) - Si crea in automatico un file
App_Start/SwaggerConfig.cs, centralizzato, dal quale è possibile configurare tutto.
Route personalizzata
[modifica]Siccome runnare su /swagger ci fa schifo, cambiamo l'impostazione della route aggiungendo il parametro routeTemplate alla configurazione di Swagger e SwaggerUI (in /App_Start/SwaggerConfig.cs)
GlobalConfiguration.Configuration.EnableSwagger("docs/{apiVersion}", c => { c.SingleApiVersion("v1", "Designbest REST-API"); /* ... */ })
GlobalConfiguration.Configuration.EnableSwaggerUi("doc/{*assetPath}", c => { c.DocumentTitle("Designbest REST-API"); /* ... */ })
In questo modo runniamo su /doc/index (ricordiamoci /index!).
Iniettare CSS e JavaScript
[modifica]Per personalizzare i colori dell'interfaccia della documentazione è possibile inserire un proprio CSS custom.
- Creare un file CSS in un percorso dell'applicazione, es
/Content/css/swagger-custom.css - Cliccare sulle proprietà e nella Build Action impostare Embedded Resource (e Copy to Output directory mettere Copy always)
- A questo punto il nome logico della risorsa sarà
App_Namespace.Folder.File, ad esDB_RestService.Content.css.swagger-custom.css - Dalle impostazioni della SwaggerUI usare il comando:
c.InjectStylesheet(thisAssembly, "DB_RestService.Content.css.swagger-custom.css");
Stessa solfa per il javascript.
Perché dovrei mettere del javascript in una documentazione?
Per esempio per personalizzare la favicon che da CSS non può essere alterata:
c.InjectJavaScript(thisAssembly, "DB_RestService.Content.js.swagger-custom.js");
Il contenuto del js potrebbe essere:
(function () {
var link = document.querySelector("link[rel*='icon']") || document.createElement('link');
document.head.removeChild(link);
link = document.querySelector("link[rel*='icon']") || document.createElement("link");
link.type = "image/x-icon";
link.rel = "shortcut icon";
link.href = "https://www.designbest.com/favicon.png";
document.getElementsByTagName("head")[0].appendChild(link);
})();
Aggiungere i commenti delle funzioni e delle proprietà dei modelli
[modifica]Per fare in modo che Swagger inserisca anche le documentazioni inline scritte dallo sviluppatore
è necessario abilitare la spunta XML documentation file dalle proprietà del progetto, pannello Build.
Remember, abilitare la spunta per tutte le configurazioni (DEBUG; RELEASETEST, RELEASE).
Gestione parametri Header (es. token)
[modifica]Se le API sono protette da autenticazione con bearer token o basi authentication l'interfaccia di swagger deve dare la possibilità di effettuare l'autenticazione.
Per aggiungere un nuovo campo di input con le specifiche adeguate si rende necessario:
- Implementare l'interfaccia IOperationFilter (di Swagger.Net)
- Notificare nella configurazione la presenza di questa implementazione
Di seguito un esempio di implementazione di Bearer Token
public class SwaggerOperationFilter : IOperationFilter {
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) {
if (operation == null)
return;
if (operation.parameters == null)
operation.parameters = new List<Parameter>();
Parameter authorizationParam = new Parameter {
description = "Token da fornire per l'accesso al servizio",
required = true,
@in = "header",
name = "Authorization",
type = "string",
@default = "Bearer "
};
operation.parameters.Add(authorizationParam);
operation.responses.Add("400", new Response {
description = "I dati inviati sono errati o incompleti",
examples = new Dictionary<string, object>() {
{ "application/json", new { Message= "...messaggio di errore..." } }
}
});
operation.responses.Add("401", new Response {
description = "Chiave di autorizzazione non valida o mancante",
examples = new Dictionary<string, object>() {
{ "application/json", new {Message= "Autorizzazione negata per la richiesta."} }
}
});
operation.responses.Add("500", new Response {
description = "Si è verificato un errore durante l'esecuzione della procedura",
examples = new Dictionary<string, object>() {
{ "application/json", new {Message= "...messaggio di errore..."} }
}
});
}
}
Piazzato ad esempio in un folder /Filters.
All'interno di SwaggerConfig.cs segnalare l'operation filter appena implementato tramite la riga
c.OperationFilter<SwaggerOperationFilter>();
dentro a EnableSwagger("...", c=> { ... }...