Voir le flux RSS

Blog de Hinault Romaric (.NET Core, ASP.NET Core, Azure, DevOps)

[Actualité] Aller plus loin avec la configuration de Swagger dans une Web API ASP.NET Core

Noter ce billet
par , 21/12/2017 à 04h47 (1280 Affichages)
Dans mon premier billet de blog sur Swagger, j’ai présenté comment intégrer Swagger dans une application ASP.NET Core Web API et générer la documentation. Dans le second billet, j’ai démystifié la spécification OpenAPI (Swagger specification) afin que vous soyez en mesure de comprendre le endpoint JSON généré par le framework Swagger pour notre Web API ASP.NET Core.
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 - Visualiser dans une fenêtre à part
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 - Visualiser dans une fenêtre à part
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 - Visualiser dans une fenêtre à part
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.

Nom : img5.png
Affichages : 2425
Taille : 28,9 Ko

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 - Visualiser dans une fenêtre à part
1
2
3
4
5
        [HttpGet]
        public IEnumerable<Customer> GetAll()
        {
            return Customers;
        }

Swagger produit la réponse suivante :

Nom : img6.png
Affichages : 2294
Taille : 5,5 Ko

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 - Visualiser dans une fenêtre à part
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 - Visualiser dans une fenêtre à part
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 - Visualiser dans une fenêtre à part
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 :

Nom : img7.1.png
Affichages : 2258
Taille : 4,2 Ko

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 - Visualiser dans une fenêtre à part
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 :

Nom : img8.png
Affichages : 2280
Taille : 9,0 Ko

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 - Visualiser dans une fenêtre à part
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 - Visualiser dans une fenêtre à part
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 - Visualiser dans une fenêtre à part
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 - Visualiser dans une fenêtre à part
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 - Visualiser dans une fenêtre à part
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 :

Nom : img9.png
Affichages : 2324
Taille : 35,6 Ko


Dans l’interface swagger-ui, on obtient ce qui suit :

Nom : img10.png
Affichages : 2296
Taille : 26,9 Ko

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 :

Nom : img11.png
Affichages : 2292
Taille : 11,5 Ko

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 - Visualiser dans une fenêtre à part
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 - Visualiser dans une fenêtre à part
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!

Envoyer le billet « Aller plus loin avec la configuration de Swagger dans une Web API ASP.NET Core » dans le blog Viadeo Envoyer le billet « Aller plus loin avec la configuration de Swagger dans une Web API ASP.NET Core » dans le blog Twitter Envoyer le billet « Aller plus loin avec la configuration de Swagger dans une Web API ASP.NET Core » dans le blog Google Envoyer le billet « Aller plus loin avec la configuration de Swagger dans une Web API ASP.NET Core » dans le blog Facebook Envoyer le billet « Aller plus loin avec la configuration de Swagger dans une Web API ASP.NET Core » dans le blog Digg Envoyer le billet « Aller plus loin avec la configuration de Swagger dans une Web API ASP.NET Core » dans le blog Delicious Envoyer le billet « Aller plus loin avec la configuration de Swagger dans une Web API ASP.NET Core » dans le blog MySpace Envoyer le billet « Aller plus loin avec la configuration de Swagger dans une Web API ASP.NET Core » dans le blog Yahoo

Mis à jour 29/07/2018 à 19h33 par LittleWhite (Coloration du code)

Catégories
DotNET , ASP.NET , .NET Core , ASP.NET Core

Commentaires