Dernièrement, pour l’un de nos clients, nous nous sommes demandé comment générer un SDK automatiquement sans devoir maintenir un nouveau projet. Après avoir comparé plusieurs pistes, nous avons trouvé la solution idéale : OpenApi Generator.

Nous allons voir le fonctionnement de cet outil, sa personnalisation et son intégration dans notre pipeline CI/CD.

OpenAPI

Avant de plonger dans le fonctionnement de ce générateur, nous devons clarifier un point : qu’est-ce qu’OpenAPI.

La définition officielle est :

The OpenAPI Specification (OAS) defines a standard, language-agnostic interface to RESTful APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic.

Ce standard nous permet donc de documenter nos APIs REST en JSON ou YAML. À l’aide de cette spécification, nous pouvons décrire le fonctionnement de notre API en détails comme les endpoints disponibles, leurs paramètres, le type d’authentification nécessaire, etc.

Si vous ne connaissez pas cet outil, une fois mis en place dans vos projets, il vous permettra d’avoir une documentation claire et sous un format adopté par tous ! De plus, selon la structure de votre projet, cette documentation pourra être générée automatiquement grâce à de nombreux outils disponibles.

Note : Vous pouvez tester les commandes présentées dans la suite de cet article avec le Pet Store, c’est l’exemple le plus connu. Vous pouvez le visualiser ici :  https://petstore3.swagger.io/ ou télécharger le fichier JSON : https://petstore3.swagger.io/api/v3/openapi.json.

OpenAPI Generator

OpenAPI Generator va utiliser un fichier JSON ou YAML (correspondant à votre OpenApi spécification) pour générer un SDK, du code serveur ou encore de la documentation en HTML par exemple. Le nombre de langage supporté est impressionnant comme vous pouvez voir ci-dessous :

  • ActionScript,
  • Ada,
  • Apex,
  • Bash,
  • C,
  • C#,
  • C++,
  • Clojure,
  • Crystal,
  • Dart,
  • Elixir,
  • Elm,
  • Eiffel,
  • Erlang,
  • Go,
  • Groovy,
  • Haskell,
  • Java,
  • k6,
  • Kotlin,
  • Lua,
  • Nim,
  • Node.js/JavaScript,
  • ObjectiveC,
  • OCaml,
  • Perl,
  • PHP,
  • PowerShell,
  • Python,
  • R,
  • Ruby,
  • Rust,
  • Scala,
  • Swift,
  • Typescript
  • Aurelia,
  • Axios,
  • Fetch,
  • Inversify,
  • jQuery,
  • Nestjs,
  • Node,
  • redux-query,
  • Rxjs

Vous pouvez retrouver des détails sur tous les langages présents ici.

Plusieurs étapes sont nécessaires pour générer un SDK. La première chose à faire est d’installer l’outil, soit en ligne de commande soit en important  le plugin correspondant à votre projet. Dans notre projet Scala, nous avons utilisé ce plugin SBT: https://github.com/OpenAPITools/sbt-openapi-generator, qui est simplement un wrapper autour de l’outil en ligne de commande. Cela nous a permis d’intégrer la génération de code facilement dans notre pipeline CI/CD actuel.

Dans ce post, nous allons utiliser l’outil en ligne de commande, nous pouvons l’installer avec : https://openapi-generator.tech/docs/installation et nous générerons un SDK en Scala-Akka.

1. Étapes pour générer votre SDK

a. Valider le fichier OpenAPI

Au lancement de la commande suivante :

openapi-generator validate -i PATH_TO_YOUR_FILE.[json | yaml]

Votre fichier va être parsé et l’outil validera que le fichier est conforme à la spécification OpenAPI. Si ce n’est pas le cas, cela permet de détecter des problèmes en amont dans votre pipeline CI/CD par exemple.

Dans le cas d’un fichier valide, vous devriez voir :

No validation issues detected.

Autrement, toutes les recommandations ou erreurs à résoudre dans votre fichier comme :

Errors:
    - attribute info.title is missing
Warnings:
    - Unused model: Address
    - Unused model: Customer

b. Générer le code

Encore une fois, une seule commande suffit à générer tout votre code, des options sont disponibles pour personnaliser le rendu, mais nous y reviendrons dans la partie suivante.

openapi-generator generate -g scala-akka -o NAME_OUTPUT_FOLDER -i PATH_TO_YOUR_FIILE

Vous pourrez retrouver votre code sous le dossier NAME_OUTPUT_FOLDER.

2. Customisation

a. Templating

Comme vous pouvez le voir avec les étapes ci-dessus, cette solution est extrêmement simple à utiliser. Cependant, la plupart du temps, le code généré sans personnalisation ne sera pas adapté à 100% à vos besoins. Pour résoudre ce problème, il faut comprendre que la logique interne du générateur a été faite pour être flexible et modulable. En effet, le générateur va seulement utiliser des Mustache templates en remplaçant toutes les clés par les valeurs présentes dans votre fichier YAML ou JSON. Par conséquent, nous pouvons modifier ces templates pour les adapter à nos besoins. Vous pouvez tous les retrouver ici ou alors plus simplement, télécharger les templates de votre langage directement avec cette commande :

openapi-generator author template -g YOUR_LANGUAGE

Par exemple, pour notre client, nous avons modifié le fichier build.sbt avec certaines informations afin de publier notre jar. L’utilisation des templates a permis de faire ce changement très facilement en modifiant simplement le  fichier suivant : https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/scala-akka-client/build.sbt.mustache.

Pour générer le code il faut ensuite préciser le dossier contenant nos templates modifiées avec le paramètre -t ou –template :

openapi-generator generate -g scala-akka -t PATH_TO_FOLDER_WITH_CUSTOM_TEMPLATES -o NAME_OUTPUT_FOLDER -i PATH_TO_YOUR_FIILE

Petite précision, vous n’avez pas besoin de garder tous les templates téléchargés. Vous pouvez laisser seulement ceux modifiés et le générateur utilisera les templates par défaut à la place de ceux manquants.

b. Personnalisation

Le générateur accepte des paramètres directement depuis un fichier de configuration. Par exemple, pour scala-akka, nous avons tous ces paramètres disponibles : https://openapi-generator.tech/docs/generators/scala-akka/Nous pouvons alors utiliser ces paramètres pour, par exemple, convertir des types suivant nos besoins :

Automatiquement le générateur va convertir le type date-time de la spécification OpenAPI en java.time.OffsetDateTime. Or nous voudrions un java.time.Instant à la place. Nous pouvons, grâce à la configuration, spécifier ce mapping qui sera pris en considération par la suite. Ainsi, vous pouvez préciser pour chaque type de votre fichier JSON ou YAML, l’équivalent dans le langage cible, si le choix par défaut ne vous convient pas.

Il y a des paramètres différents en fonction de chaque langage donc pensez à jeter un coup d’œil à cette page.

3. Intégration au pipeline CI/CD

Dans le projet concerné, nous utilisons Scala avec SBT et Jenkins pour automatiser notre CI/CD.  Comme dit précédemment, nous avons choisi d’utiliser un plugin SBT qui est un wrapper autour de l’outil en ligne de commande afin de faciliter l’intégration dans notre processus.

Le schéma ci-dessous résume l’ensemble :

Intégration de l’outil dans notre processus

Image 1 : Intégration de l’outil dans notre processus

Grâce au plugin SBT, le flow est assez simple étant donné que l’on peut générer nos SDK et les publier directement depuis SBT. 

À chaque Release de notre projet privé, nous générons la spécification OpenAPI durant la compilation grâce à différents outils misent en place. Ensuite, on utilise OpenAPI Generator pour valider notre spécification. Si le fichier est valide, on génère du code client en Scala, Java et Python. Étendre à d’autres langages se résume à ajouter son nom dans la liste des langages puis relancer le processus, c’est tout. Une fois qu’un SDK est généré, des tests sont aussi générés automatiquement. Par conséquent, on lance ces tests pour vérifier la validité du code.

Une fois toutes ces étapes réussies, on met à disposition les SDKs sur un emplacement public. À chaque release, nous avons donc un SDK dans chaque langage qui suit les mêmes versions que le projet cible.

Synthèse

En conclusion, OpenAPI Generator est une solution simple à mettre en place si vous avez déjà une spécification OpenAPI pour votre projet. Nous pouvons, avec un minimum d’effort, mettre à disposition de nos clients des SDKs dans de nombreux langages. Ces SDKs simplifient grandement les efforts nécessaires pour intégrer nos APIs par nos clients sans ajouter une charge de maintenance de notre côté étant donné que tout est automatisé de bout en bout !

J’espère que je vous ai donné envie d’essayer cet outil et je reste à votre disposition pour toutes questions.

Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Anti-spam image