Dans ce billet, nous verrons quelques options de configuration qu’offre Swagger pour ASP.NET Core.
I - Générer différentes versions de la documentation
Si vous apportez une mise à jour à votre application et publiez une seconde version de votre API, vous pouvez générer une seconde documentation Swagger pour la version 2, tout en maintenant la documentation de la version précédente. Pour le faire, vous devez simplement ajouter une nouvelle documentation au générateur Swagger :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "SwaggerDemo", Version = "v1" }); c.SwaggerDoc("v2", new Info { Version = "v2", Title = "SwaggerDemo API", Description = "Customers API to demo Swagger", TermsOfService = "None", Contact = new Contact { Name = "Hinault Romaric", Email = "hinault@monsite.com", Url = "http://rdonfack.developpez.com/" }, License = new License { Name = "Apache 2.0", Url = "http://www.apache.org" } }); }); |
Comme vous pouvez le constater avec le code ci-dessous. La classe Info contient plusieurs autres propriétés. J’ai donc utilisé celles-ci pour offrir une description plus complète de mon API, avec des informations supplémentaires comme la licence, les termes d’utilisation, etc.
Lorsque vous générez plusieurs documentations pour votre API, vous devez ternir compte des éléments suivants :
- Le premier argument de la méthode SwaggerDoc doit permettre d’identifier la documentation. Il doit donc être unique. Couramment, il s’agit du numéro de version (v1, v2, etc.). Cet argument doit être URI-friendly. Il est également utilisé pour le chemin d’accès au document JSON correspondant. Pour notre cas, la documentation de la V1 sera accessible à partir du lien « /swagger/v1/swagger.json » et celle de la V2 à partir du lien « /swagger/v2/swagger.json ».
- Les actions à exclure dans la documentation de la v1 et à inclure uniquement dans la documentation de la v2 doivent être décorées avec l’attribut [ApiExplorerSettings(GroupName = "v2")] :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | [HttpDelete("{id}")] [ApiExplorerSettings(GroupName = "v2")] public IActionResult Delete(int id) { var customer = Customers.FirstOrDefault(t => t.Id == id); if (customer == null) { return NotFound(); } Customers.Remove(customer); return new NoContentResult(); } |
Une fois que vous avez modifié le générateur Swagger pour générer plusieurs documentations, vous devez également apporter une modification au middleware SwaggerUI pour que ces documentations soient prises en compte au niveau de l’interface graphique.
Pour le faire, vous devez simplement spécifier les différents endpoints de vos documentations lorsque vous ajoutez le middleware :
Code c# : | Sélectionner tout |
1 2 3 4 5 | app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "SwaggerDemo v1"); c.SwaggerEndpoint("/swagger/v2/swagger.json", "SwaggerDemo v2"); }); |
Désormais, lorsque vous accéderez à l’interface utilisateur de Swagger, vous aurez à droite au-dessus une liste déroulante qui vous permettra de switcher entre les différentes documentations.
II - Améliorer la section réponse de la documentation
Par défaut, Swagger génère chaque réponse dans la documentation avec le code 200 et pour description « Success ». Il s’agit du code standard utilisé pour une requête HTTP réussie. Toutefois, Swagger est capable de fournir un document plus complet pour une réponse d’une action. Si l’action retourne un DTO, par exemple, alors il sera automatiquement utilisé pour générer un schéma pour le corps de la réponse.
Par exemple, pour l’action suivante :
Code c# : | Sélectionner tout |
1 2 3 4 5 | [HttpGet] public IEnumerable<Customer> GetAll() { return Customers; } |
Swagger produit la réponse suivante :
Pour une méthode d’action qui retourne un IActionResult au lieu d’un DTO, Swagger ne sera pas en mesure de générer une réponse explicite. Il générera simplement une réponse avec le code 200 et la description succès.
Par exemple, pour la méthode d’action suivante :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 | [HttpGet("{id}", Name = "GetById")] public IActionResult GetById(int id) { var custormer = Customers.FirstOrDefault(c => c.Id == id); if (custormer == null) { return NotFound(); } return new ObjectResult(custormer); } |
Swagger va produire dans la documentation la réponse suivante :
Code json : | Sélectionner tout |
1 2 3 4 5 6 7 | "responses": { "200": { "description": "Success" } } |
Pourtant, c’est un objet (un DTO) de type Customer qui est encapsulé dans la réponse HTTP. Pour remédier à cela et permettre à l’utilisateur de savoir le type de données qui est retourné dans la réponse, vous pouvez décorer la méthode d’action avec l’attribut [ProducesResponseType] comme suit :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | [HttpGet("{id}", Name = "GetById")] [ProducesResponseType(typeof(Customer), 200)] public IActionResult GetById(int id) { var custormer = Customers.FirstOrDefault(c => c.Id == id); if (custormer == null) { return NotFound(); } return new ObjectResult(custormer); } |
Et l’on va obtenir comme résultat ce qui suit :
Si plusieurs réponses différentes peuvent être retournées pour votre méthode d’action, vous pouvez utiliser cet attribut pour décrire ces différentes réponses.
Par exemple, pour la méthode d’action ci-dessus, s’il n’existe aucun client ayant l’ID passé en paramètre, nous aurons un NotFound() comme réponse. Par ailleurs, si le service n’est pas disponible, nous aurons l’erreur HTTP 500, pour « Internal Server Error ».
Pour spécifier cela dans notre documentation Swagger, nous allons utiliser l’attribut [ProducesResponseType] comme suit :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | [HttpGet("{id}", Name = "GetById")] [ProducesResponseType(typeof(Customer), 200)] [ProducesResponseType(typeof(NotFoundResult), 404)] [ProducesResponseType(typeof(void), 500)] public IActionResult GetById(int id) { var custormer = Customers.FirstOrDefault(c => c.Id == id); if (custormer == null) { return NotFound(); } return new ObjectResult(custormer); } |
Ce qui va produire le résultat suivant :
III - Utiliser les commentaires XML dans le code pour enrichir sa documentation
Dans le code, au début de chaque méthode ou classe, les commentaires XML sont couramment utilisés pour donner une brève description de la méthode ou classe. Ces commentaires peuvent être utilisés par Swagger pour enrichir le contenu de la documentation qui est générée. La prise en compte des commentaires XML se fait en quatre étapes :
1. Inclure les commentaires XML dans vos méthodes d’action :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /// <summary> /// Retourne un client specifique à partir de son id /// </summary> /// <remarks>Je manque d'imagination</remarks> /// <param name="id">id du client a retourné</param> /// <response code="200">client selectionné</response> /// <response code="404">client introuvable pour l'id specifié</response> /// <response code="500">Oops! le service est indisponible pour le moment</response> [HttpGet("{id}", Name = "GetById")] [ProducesResponseType(typeof(Customer), 200)] [ProducesResponseType(typeof(NotFoundResult), 404)] [ProducesResponseType(typeof(void), 500)] public IActionResult GetById(int id) { var custormer = Customers.FirstOrDefault(c => c.Id == id); if (custormer == null) { return NotFound(); } return new ObjectResult(custormer); } |
2. Modifier les propriétés du projet pour permettre la génération du fichier XML de documentation
Pour le faire, vous devez éditer le fichier .csproj et ajouter le contenu XML suivant :
Code xml : | Sélectionner tout |
1 2 3 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <DocumentationFile>bin\Debug\netcoreapp2.0\SwaggerDemo.xml</DocumentationFile> </PropertyGroup> |
Une fois cela fait, si vous procédez à la génération de votre application, un fichier SwaggerDemo.xml sera créé dans le dossier de génération de cette dernière (\bin\Debug\netcoreapp2.0). Son contenu est le suivant :
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?xml version="1.0"?> <doc> <assembly> <name>SwaggerDemo</name> </assembly> <members> <member name="M:SwaggerDemo.Controllers.CustomersController.GetById(System.Int32)"> <summary> Retourne un client specifique à partir de son id </summary> <remarks>Je manque d'imagination</remarks> <param name="id">id du client a retourné</param> <response code="200">client selectionné</response> <response code="404">client introuvable pour l'id specifié</response> <response code="500">Oops! le service est indisponible pour le moment</response> </member> </members> </doc> |
Vous allez remarquer qu’un message d’avertissement est dorénavant affiché pour chaque classe et méthode qui ne sont pas annotées avec les commentaires XML. Pour supprimer cela, vous devez éditer le fichier .csproj et ajouter le numéro de warning 1591, afin que ce dernier soit ignoré par le compilateur :
Code xml : | Sélectionner tout |
1 2 3 4 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <DocumentationFile>bin\Debug\netcoreapp2.0\SwaggerDemo.xml</DocumentationFile> <NoWarn>1591</NoWarn> </PropertyGroup> |
3.Modifier la configuration de Swashbuckle pour exploiter le fichier XML généré
Vous devez éditer le fichier Startup.cs et modifier la configuration de Swashbuckle pour qu’il puisse inclure le document XML généré dans la documentation :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "SwaggerDemo", Version = "v1" }); var filePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "SwaggerDemo.xml"); c.IncludeXmlComments(filePath); }); |
4. Exécutez votre application et accédez au endpoint JSON Swagger pour visualiser le résultat :
Dans l’interface swagger-ui, on obtient ce qui suit :
IV- Gestion des actions et propriétés obsolètes
Lorsqu’une action ou une propriété du modèle est décorée avec l’attribut [Obsolete], Swagger affiche automatiquement un message d’avertissement pour la méthode d’action :
Si vous souhaitez continuer à intégrer ces dernières dans votre documentation sans aucun avertissement, vous pouvez utiliser les méthodes IgnoreObsoleteActions() et IgnoreObsoleteProperties() lors de la configuration de Swagger comme suit :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 | services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "SwaggerDemo", Version = "v1" }); c.IgnoreObsoleteActions(); c.IgnoreObsoleteProperties(); }); |
V- Exclure une méthode d’action de la documentation
Pour exclure une méthode d’action, vous devez décorer cette dernière avec l’attribut ApiExplorerSettings, comme suit :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 | [HttpGet] [ApiExplorerSettings(IgnoreApi = true)] public IEnumerable<Customer> GetAll() { return Customers; } |
Vous en savez désormais un peu plus comment vous pouvez améliorer votre documentation Swagger. Bon coding!