Documenter les APIs avec Swagger (2/4) — Le framework Swagger

Dans cette série d’articles, je vais introduire les différents outils de Swagger. Swagger est un outil très pratique de documentation des APIs. Il permet de générer de la documentation “vivante”, permettant ainsi que la documentation soit toujours à jour, ce qui est très difficile à réaliser sans ce genre d’outil. Il permet également de générer du code automatiquement, permettant au développeur de se concentrer sur le coeur de son activité. Enfin, il repose sur un format de spécifications open source.

Cet article est donc décomposé en quatre parties :

Le framework Swagger (https://github.com/swagger-api) comprend plusieurs sous-projets répondant à un objectif bien précis. Voici ceux que l’on va aborder ici :

  • Swagger Editor,
  • Swagger UI,
  • Swagger CodeGen.

Swagger Editor

Swagger Editor (https://github.com/swagger-api/swagger-editor) permet d’éditer les fichiers de spécification au format YAML. Autrement dit, il permet de créer un contrat.

Lancer Swagger Editor :

docker run \
-d \
-p 82:8080 \
swaggerapi/swagger-editor

La sortie de la commande est :

32cb780d106341769f19a72f5489b463030d8f62860dce392dae414ec89695b3

Puis dans un navigateur Web, aller à adresse http://0.0.0.0:82.

Pour importer la spécification Swagger au format Yaml et générer la documentation interactive, vous pouvez :

  • copier/coller le contenu du fichier Swagger Yaml,
  • importer un fichier depuis votre disque dur local (File | Import file),
  • importer un fichier depuis une URL (File | Import URL),

Pour générer le code source du serveur :

  • Aller à http://0.0.0.0:82
  • copier/coller le contenu du fichier Swagger Yaml
  • ou importer un fichier depuis votre disque dur local (File | Import file),
  • ou importer un fichier depuis une URL (File | Import URL),

Pour générer le code source du serveur, utiliser : Generate Server | nodejs-server

Puis décompresser le code source généré :

mv ~/Downloads/nodejs-server-server-generated.zip .
unzip nodejs-server-server-generated.zip
rm nodejs-server-server-generated.zip

Afficher le contenue du fichier ContactService.js :

cat nodejs-server-server/service/ContactService.js

Le contenu de ce fichier est :

'use strict';
/**
* Creates a new contact
*
* contact ContactCreateRequest The contact data
* no response value expected for this operation
**/
exports.createContact = function(contact) {
return new Promise(function(resolve, reject) {
resolve();
});
}
/**
* Gets the list of contacts
*
*
* returns ListContactsResponse
**/
exports.getContacts = function() {
return new Promise(function(resolve, reject) {
var examples = {};
examples['application/json'] = "";
if (Object.keys(examples).length > 0) {
resolve(examples[Object.keys(examples)[0]]);
} else {
resolve();
}
});
}

Installer ensuite les dépendances :

cd nodejs-server-servernpm install

La sortie de la commande est :

npm WARN deprecated superagent@1.8.5: Please note that v5.0.1+ of superagent removes User-Agent header by default, therefore you may need to add it yourself (e.g. GitHub blocks requests without a User-Agent header).  This notice will go away with v5.0.2+ once it is released.
░░░░░░⸩ ⠹ build:multer: sill linkStuff multer@1.4.2 has /Users/bruKlease
> core-js@2.6.9 postinstall /Users/brunodelb/devops/notebooks/documentation/Swagger/nodejs-server-server/node_modules/core-js
> node scripts/postinstall || echo "ignore"
Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
> https://opencollective.com/core-js
> https://www.patreon.com/zloirock
Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)npm notice created a lockfile as package-lock.json. You should commit this file.[K
added 147 packages from 83 contributors and audited 401 packages in 4.731s
found 5 vulnerabilities (2 low, 2 moderate, 1 high)
run `npm audit fix` to fix them, or `npm audit` for details

Lancer le serveur NodeJS :

node index

Cette commande affiche ceci dans le terminal :

Your server is listening on port 8080 (http://localhost:8080)
Swagger-ui is available on http://localhost:8080/docs

Pour générer le code source du client utiliser : Generate Client | javascript

Puis décompresser le code source généré :

mv ~/Downloads/javascript-client-generated.zip .
unzip javascript-client-generated.zip
rm javascript-client-generated.zip

Le fichier est décompressé :

Archive:  javascript-client-generated.zip
inflating: javascript-client/src/index.js
inflating: javascript-client/src/model/ListContactsResponse.js
inflating: javascript-client/src/model/ContactResponse.js
inflating: javascript-client/src/model/ContactCreateRequest.js
inflating: javascript-client/src/api/ContactApi.js
inflating: javascript-client/src/ApiClient.js
inflating: javascript-client/mocha.opts
inflating: javascript-client/README.md
inflating: javascript-client/docs/ListContactsResponse.md
inflating: javascript-client/docs/ContactCreateRequest.md
inflating: javascript-client/docs/ContactResponse.md
inflating: javascript-client/docs/ContactApi.md
inflating: javascript-client/.swagger-codegen-ignore
inflating: javascript-client/.swagger-codegen/VERSION
inflating: javascript-client/.travis.yml
inflating: javascript-client/test/model/ContactResponse.spec.js
inflating: javascript-client/test/model/ListContactsResponse.spec.js
inflating: javascript-client/test/model/ContactCreateRequest.spec.js
inflating: javascript-client/test/api/ContactApi.spec.js
inflating: javascript-client/git_push.sh
inflating: javascript-client/package.json

Swagger UI

Swagger UI (https://github.com/swagger-api/swagger-ui) est un outil interactif permettant d’afficher et d’exécuter les fichiers de spécification Swagger. Il permet de publier une documentation interactive et attrayante de l’API.

Vous pouvez utiliser android, bash, dar, go, java, jmeter, kotlin, php, python, swift4 ou typescript-node.

Lancer Swagger UI :

docker run \
-d \
-p 83:8080 \
-e SWAGGER_JSON=/app/swagger.yaml \
-v $PWD:/app \
swaggerapi/swagger-ui

Le résultat de la commande est :

13d328f7157def0eae791631518cf1583fc29ee06476a538d9cd4fa84b63ae37

Aller à l’adresse http://0.0.0.0:83 pour accéder à l’interface utilisateur de Swagger UI.

Swagger Codegen

Swagger Codegen (https://github.com/swagger-api/swagger-codegen) permet de lire des fichiers de spécification et de générer le code squelette du client et du serveur de l’API dans différents langages.

Pour connaître la liste des langages supportés :

docker run \
--rm \
-v $PWD:/local \
swaggerapi/swagger-codegen-cli langs

Voici le résultat de la commande :

Available languages: [ada, ada-server, akka-scala, android, apache2, apex, aspnetcore, bash, csharp, clojure, cwiki, cpprest, csharp-dotnet2, dart, elixir, elm, eiffel, erlang-client, erlang-server, finch, flash, python-flask, go, go-server, groovy, haskell-http-client, haskell, jmeter, jaxrs-cxf-client, jaxrs-cxf, java, inflector, jaxrs-cxf-cdi, jaxrs-spec, jaxrs, msf4j, java-pkmst, java-play-framework, jaxrs-resteasy-eap, jaxrs-resteasy, javascript, javascript-closure-angular, java-vertx, kotlin, lua, lumen, nancyfx, nodejs-server, objc, perl, php, powershell, pistache-server, python, qt5cpp, r, rails5, restbed, ruby, rust, rust-server, scala, scala-gatling, scala-lagom-server, scalatra, scalaz, php-silex, sinatra, slim, spring, dynamic-html, html2, html, swagger, swagger-yaml, swift4, swift3, swift, php-symfony, tizen, typescript-aurelia, typescript-angular, typescript-inversify, typescript-angularjs, typescript-fetch, typescript-jquery, typescript-node, undertow, ze-ph, kotlin-server]

Pour valider une spécification :

docker run \
--rm \
-v $PWD:/app \
swaggerapi/swagger-codegen-cli validate -i /app/swagger.yaml

Cette commande retourne le résultat suivant :

Validating spec file (/app/swagger.yaml)

Pour PHP :

docker run \
--rm \
-v ${PWD}:/local \
swaggerapi/swagger-codegen-cli \
generate -i /local/swagger.yaml -l php -o /local/out

La sortie de la commande est :

[main] INFO io.swagger.parser.Swagger20Parser - reading from /local/swagger.yaml
[main] WARN io.swagger.codegen.ignore.CodegenIgnoreProcessor - Output directory does not exist, or is inaccessible. No file (.swagger-codegen-ignore) will be evaluated.
[main] WARN io.swagger.codegen.DefaultGenerator - 'host' not defined in the spec. Default to 'localhost'.
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/lib/Model/ContactCreateRequest.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/test/Model/ContactCreateRequestTest.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/docs/Model/ContactCreateRequest.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/lib/Model/ContactResponse.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/test/Model/ContactResponseTest.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/docs/Model/ContactResponse.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/lib/Model/ListContactsResponse.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/test/Model/ListContactsResponseTest.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/docs/Model/ListContactsResponse.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/lib/Api/ContactApi.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/test/Api/ContactApiTest.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/docs/Api/ContactApi.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/lib/ApiException.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/lib/Configuration.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/lib/ObjectSerializer.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/lib/Model/ModelInterface.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/lib/HeaderSelector.php
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/composer.json
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/README.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/phpunit.xml.dist
[main] INFO io.swagger.codegen.DefaultGenerator - writing file /local/out/SwaggerClient-php/.travis.yml
[main] INFO io.swagger.codegen.DefaultGenerator - writing file /local/out/SwaggerClient-php/.php_cs
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/SwaggerClient-php/git_push.sh
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/.swagger-codegen-ignore
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/.swagger-codegen/VERSION

Vérifier que le code a bien été généré :

ls $PWD/out

Cette commande montre bien qu’un répertoire a été créé :

SwaggerClient-php

Nettoyons notre répertoire en supprimant le sous-répertoire out.

rm -rf $PWD/out

Pour Python :

docker run \
--rm \
-v $PWD:/local \
swaggerapi/swagger-codegen-cli \
generate -i /local/swagger.yaml -l python -o /local/out

La sortie de cette commande est :

[main] INFO io.swagger.parser.Swagger20Parser - reading from /local/swagger.yaml
[main] WARN io.swagger.codegen.ignore.CodegenIgnoreProcessor - Output directory does not exist, or is inaccessible. No file (.swagger-codegen-ignore) will be evaluated.
[main] WARN io.swagger.codegen.DefaultGenerator - 'host' not defined in the spec. Default to 'localhost'.
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/swagger_client/models/contact_create_request.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/test/test_contact_create_request.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/docs/ContactCreateRequest.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/swagger_client/models/contact_response.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/test/test_contact_response.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/docs/ContactResponse.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/swagger_client/models/list_contacts_response.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/test/test_list_contacts_response.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/docs/ListContactsResponse.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/swagger_client/api/contact_api.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/test/test_contact_api.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/docs/ContactApi.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/README.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/tox.ini
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/test-requirements.txt
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/requirements.txt
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/swagger_client/configuration.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/swagger_client/__init__.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/swagger_client/models/__init__.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/swagger_client/api/__init__.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/test/__init__.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/git_push.sh
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/.gitignore
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/.travis.yml
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/setup.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/swagger_client/api_client.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/swagger_client/rest.py
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/.swagger-codegen-ignore
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/.swagger-codegen/VERSION

Vérifier que les fichiers ont bien été générés :

ls ./out

On voit bien que des fichiers ont été générés :

README.md		requirements.txt	test
docs setup.py test-requirements.txt
git_push.sh swagger_client tox.ini

Nettoyons notre répertoire en supprimant le sous-répertoire out.

rm -rf $PWD/out

Pour NodeJS :

docker run \
--rm \
-v ${PWD}:/local \
swaggerapi/swagger-codegen-cli \
generate -i /local/swagger.yaml -l nodejs-server -o /local/out

La sortie du conteneur Docker donne :

[main] INFO io.swagger.parser.Swagger20Parser - reading from /local/swagger.yaml
[main] WARN io.swagger.codegen.ignore.CodegenIgnoreProcessor - Output directory does not exist, or is inaccessible. No file (.swagger-codegen-ignore) will be evaluated.
[main] WARN io.swagger.codegen.languages.NodeJSServerCodegen - 'host' in the specification is empty or undefined. Default to http://localhost.
[main] WARN io.swagger.codegen.DefaultGenerator - 'host' not defined in the spec. Default to 'localhost'.
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/service/ContactService.js
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/controllers/Contact.js
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/utils/writer.js
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/api/swagger.yaml
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/index.js
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/package.json
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/README.md
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/.swagger-codegen-ignore
[main] INFO io.swagger.codegen.AbstractGenerator - writing file /local/out/.swagger-codegen/VERSION

Voyons les fichiers générés :

ls ./out

Le conteneur Docker a bien généré des fichiers :

README.md	controllers	package.json	utils
api index.js service

Dans cette première partie, vous avez compris les choses les plus importantes à savoir sur la spécification Swagger 2.0.

More articles on my blog http://www.DevOpsTestLab.com.

My DevOpsTestLab Youtube channel.

My LinkedIn profile: https://fr.linkedin.com/in/brunodelb

Written by

Interests in the full lifecycle: design, Agile Coaching, development, testing, DevOps, Cloud, Management 3.0, ITIL. It defines me.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store