IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

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

[Actualité] Documenter sa Web API ASP.NET Core avec Swagger

Note : 2 votes pour une moyenne de 5,00.
par , 30/11/2017 à 18h48 (6316 Affichages)
Les nombreux services et applications que nous utilisons au quotidien consomment des API pour offrir les services attendus.

Nom : img0.png
Affichages : 132216
Taille : 34,7 Ko

Une API (Application Programming Interface), selon Wikipedia, est
un ensemble normalisé de classes, de méthodes ou de fonctions qui sert de façade par laquelle un logiciel offre des services à d'autres logiciels. Elle est offerte par une bibliothèque logicielle ou un service web, le plus souvent accompagnée d'une description qui spécifie comment des programmes consommateurs peuvent se servir des fonctionnalités du programme fournisseur.
L’API a donc pour vocation d’être exploitée par une autre application. Son utilisation par les développeurs sera plus simple s’il est mis à la disposition de ceux-ci une documentation conviviale et à jour, permettant de savoir le type de requête HTTP utilisé pour appeler le service, le type de données qui est passé en paramètre, le type de données qui est retournée, comment tester le service, etc.

C’est pour répondre à ce besoin que des développeurs ont mis en place le projet Swagger. Il s’agit d’un Framework qui offre des outils permettant de générer de la documentation pour son API Web. Il offre également une interface permettant d’explorer et tester les différentes opérations offertes par le service.

Le recours à un tel outil offre de nombreux avantages au développeur :
  • la documentation est automatiquement générée à partir du code;
  • cette dernière suit le même cycle de vie que le code : tout changement au code est directement appliqué à la documentation;
  • la documentation est étroitement liée avec le code et directement livrée avec ce dernier;
  • le développeur n’a plus besoin de mettre des efforts dans la production et l’évolution de la documentation. Cela lui permet donc de se concentrer dans la mise en place de ses API.


Dans le cadre de ce billet, nous verrons comment utiliser Swagger pour créer la documentation et tester une Web API ASP.NET Core.

Outils utilisés

Pour mettre en place le projet de démonstration, j’ai utilisé les outils suivants :
  • .NET Core 2.0 ;
  • ASP.NET Core 2.0 ;
  • Swashbuckle.AspNetCore 1.0 ;
  • Visual Studio Code ;
  • le navigateur Microsoft Edge.


Vous devez obligatoirement avoir le SDK .NET Core 2.0 installé sur votre ordinateur. Vous pouvez utiliser Visual Studio Code ou tout autre éditeur de code de votre choix. Idem pour le navigateur.

Projet de démarrage

Vous pouvez télécharger le code de l’application de démarrage sur ma page GitHub, à l’adresse suivante : https://github.com/hinault/SwaggerDemo/tree/Initial

Cette application dispose d’une Web API permettant de manipuler les informations sur des clients (Customers). Cette API peut être appelée par toute autre application pour ajouter, lister, modifier et supprimer. Elle est donc constituée d’une classe entité (Customer.cs), contenue dans le dossier Models, avec le code suivant :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
  public class Customer
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string EMail { get; set; }
    }

Elle dispose également d’un contrôleur (CustomersController.cs), qui implémente les actions qui seront exécutées via des requêtes HTTP (Get, Post, Put et Delete). Le code de ce dernier est le suivant :

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 [Produces("application/json")]
    [Route("api/Customers")]
    public class CustomersController : Controller
    {
 
        List<Customer> Customers = new List<Customer>
       {
            new Customer { Id = 1, FirstName = "Hinault", LastName = "Romaric", EMail = "hr@gmail.com"},
            new Customer { Id = 2, FirstName = "Thomas", LastName = "Perrin", EMail = "thomas@outlook.com"},
            new Customer { Id = 3, FirstName = "Allan", LastName = "Croft", EMail = "allan.croft@crt.com"},
            new Customer { Id = 3, FirstName = "Sahra", LastName = "Parker", EMail = "sahra@yahoo.com"},
       };
 
        // GET: api/Customers
        [HttpGet]
        public IEnumerable<Customer> GetAll()
        {
            return Customers;
        }
 
        // GET: api/Customers/5
        [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);
        }
 
        // POST: api/Customers
        [HttpPost]
        public IActionResult Create([FromBody]Customer customer)
        {
            if(customer==null)
            {
                return BadRequest();
            }
 
            Customers.Add(customer);
 
            return CreatedAtRoute("GetById", new { id = customer.Id }, customer);
 
        }
 
        // PUT: api/Customers/5
        [HttpPut("{id}")]
        public IActionResult Update(int id, [FromBody]Customer customer)
        {
 
            if (customer== null || customer.Id != id)
            {
                return BadRequest();
            }
 
            var existingCustomer = Customers.FirstOrDefault(t => t.Id == id);
            if (customer == null)
            {
                return NotFound();
            }
 
            Customers.Remove(existingCustomer);
            Customers.Add(customer);
            return new NoContentResult();
        }
 
        // DELETE: api/ApiWithActions/5
        [HttpDelete("{id}")]
        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 l’application d’exemple téléchargée, vous pouvez l’exécuter en utilisant la commande « Dotnet run » dans le dossier racine du projet (celui contenant le fichier .csproj). Votre navigateur par défaut sera automatiquement lancé avec un onglet exécutant l’application. Ajoutez « /api/Customers » à la suite de ce lien. Vous obtiendrez la liste des clients au format JSON.

Nom : img1.png
Affichages : 6802
Taille : 26,7 Ko

NB : pour formater les données JSON dans mon navigateur, j’ai utilisé l’extension « JSON Formatter ».

Lançons-nous sans plus tarder dans le vif du sujet qui nous intéresse.

Intégration et configuration de Swagger à une application ASP.NET Core

L’intégration de Swagger à son application consiste en l’installation du package NuGet Swashbuckle.AspNetCore. Ce package permet l’ajout de trois composants à votre application :

  • Swashbuckle.AspNetCore.Swagger : ce composant permet d’exposer les objets SwaggerDocument comme une API JSON. Ce dernier utilise une implémentation de ISwaggerProvider pour générer des documents Swagger qui seront par la suite sérialisés en données JSON ;
  • Swashbuckle.AspNetCore.SwaggerGen : ce composant utilise le conteneur d’injection de dépendances de ASP.NET Core pour enregistrer une implémentation de ISwaggerProvider. Elle sera utilisée pour générer des SwaggerDocument, en fonction du contrôleur, de la route et du modèle de données ;
  • Swashbuckle.AspNetCore.SwaggerUI : composant utilisé pour généré une version intégrée de swagger-ui. Il s’agit d’une interface utilisateur qui consomme un Endpoint d’API retournant des données Swagger au format JSON. Ce composant exploite ces données pour offrir une documentation interactive, qui permettra en plus de tester le service.


Pour installer Swashbuckle.AspNetCore, vous devez utiliser le terminal intégré de Visual Studio Code ou l’invite de commande (dans le dossier contenant le fichier .csproj) et exécuter la commande suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
dotnet add package Swashbuckle.AspNetCore
Une fois le package installé, vous devez configurer votre application pour utiliser ce dernier. La configuration de Swagger se fait en deux étapes :

  • l’enregistrement du service dans le « services collection »;
  • l’intégration du middleware Swagger dans le pipeline du Framework.


Suite à l’installation du package Swashbuckle.AspNetCore, une nouvelle extension a été ajoutée pour permettre l’enregistrement du générateur de la documentation Swagger dans la liste des services.

Pour le faire, vous devez éditer le fichier Startup.cs et modifier la méthode ConfigureServices. À l’enregistrement du service, vous devez définir la version de votre API, ainsi que le titre :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
 
            services.AddSwaggerGen(c =>
          {
              c.SwaggerDoc("v1", new Info { Title = "SwaggerDemo", Version = "v1" });
           });
        }

L’utilisation de la classe Info nécessite l’ajout du using suivant dans le fichier Startup.cs :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
using Swashbuckle.AspNetCore.Swagger;
Passons maintenant à l’intégration du middleware dans le pipeline ASP.NET Core Web API. Ce dernier va permettre de générer la documentation Swagger comme un Endpoint JSON. Concrètement, la saisie du lien suivant http://monapplication/swagger/v1/swagger.json dans votre navigateur lorsque votre application est en cours d’exécution, va permettre d’afficher un document JSON.

Vous allez éditer le fichier Startup.cs, modifier la méthode Configure et ajouter la ligne de code suivante au début de celle-ci :


Si vous exécutez votre application, vous allez obtenir le résultat suivant :

Nom : img2.png
Affichages : 6688
Taille : 33,4 Ko

Le développeur qui utilisera cette API, en exploitant ce lien, sera en mesure de savoir que j’ai une API Customers qui permet de retourner des items de type Customer dans une liste (array), suite à une requête GET.

Pour exploiter correctement les informations retournées par Swagger, le développeur doit donc être en mesure de lire le document JSON qui est retourné. Pour lui faciliter la tâche, vous pouvez utiliser swagger-ui. Ce dernier interprète directement le document JSON retourné par le Endpoint Swagger et affiche ce dernier dans une interface conviviale. De plus, à partir de cette interface, l’utilisateur pourra directement tester votre API.

Pour ajouter le middleware swagger-ui à votre application, vous devez ajouter le code suivant dans la méthode Configure de la classe Startup.

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
 app.UseSwaggerUI(c =>
             {
               c.SwaggerEndpoint("/swagger/v1/swagger.json", "SwaggerDemo v1");
             });

Le code complet de cette méthode devrait ressembler à ceci :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
             app.UseSwagger();
 
             app.UseSwaggerUI(c =>
             {
               c.SwaggerEndpoint("/swagger/v1/swagger.json", "SwaggerDemo v1");
             });
 
            app.UseMvc();
 
        }

Si vous exécutez votre application, et saisissez le lien suivant http://monapplication/swagger/ dans votre navigateur, vous allez obtenir le résultat suivant :

Nom : img3.png
Affichages : 6799
Taille : 27,6 Ko

Le document affiché est interactif. Vous pouvez donc directement interagir à partir de cette interface et effectuer des requêtes sur l’API. Si vous cliquez par exemple sur la seconde méthode GET de la liste. Vous aurez un formulaire affichant l’ID du client à retourner. Au clic sur « Try it out! », la réponse retournée par l’API est affichée :

Nom : img4.png
Affichages : 6668
Taille : 28,9 Ko

C’est tout pour aujourd’hui. Dans le prochain billet, nous verrons comment modifier notre code afin d’enrichir la documentation générée par Swagger.

Restez connecté !

Envoyer le billet « Documenter sa Web API ASP.NET Core avec Swagger » dans le blog Viadeo Envoyer le billet « Documenter sa Web API ASP.NET Core avec Swagger » dans le blog Twitter Envoyer le billet « Documenter sa Web API ASP.NET Core avec Swagger » dans le blog Google Envoyer le billet « Documenter sa Web API ASP.NET Core avec Swagger » dans le blog Facebook Envoyer le billet « Documenter sa Web API ASP.NET Core avec Swagger » dans le blog Digg Envoyer le billet « Documenter sa Web API ASP.NET Core avec Swagger » dans le blog Delicious Envoyer le billet « Documenter sa Web API ASP.NET Core avec Swagger » dans le blog MySpace Envoyer le billet « Documenter sa Web API ASP.NET Core avec Swagger » dans le blog Yahoo

Mis à jour 06/12/2017 à 14h55 par ClaudeLELOUP

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

Commentaires

  1. Avatar de stailer
    • |
    • permalink
    Installé aujourd'hui sur de l'ASP.NET MVC "classique", j'aime beaucoup... Beaucoup plus évolué que le HelpPage fourni par WebApi.

    Par contre la plupart de mes actions comportent 2 attributs : HttpPost et HttpOptions (pour différentes raisons)... Tu saurais comment exclure les HttpOptions qui du coup font apparaitrent tous mes services en double dans la doc ?
  2. Avatar de Booster2ooo
    • |
    • permalink
    Citation Envoyé par stailer
    Installé aujourd'hui sur de l'ASP.NET MVC "classique", j'aime beaucoup... Beaucoup plus évolué que le HelpPage fourni par WebApi.

    Par contre la plupart de mes actions comportent 2 attributs : HttpPost et HttpOptions (pour différentes raisons)... Tu saurais comment exclure les HttpOptions qui du coup font apparaitrent tous mes services en double dans la doc ?
    Salut, regarde du côté des DocumentFilter:
    https://github.com/domaindrivendev/S...documentfilter