02/06/2024 - 11:29:55


13'30"
Introduction
TRQL Radio est bourré de services : passage au prochain morceau, passage d'un jingle, saut "quantique" dans le catalogue de musique, passage d'une locomotive, passage d'une annonce de sponsoring, passage des tops horaire, liste d'artistes correspondant à des critères spécifiques, météo, recettes de cuisine, géolocalisation et points d'intérêt aux coordonnées courantes, liste des anniversaires de naissance et de décès d'artistes, today in history, nouvelles du jour, devises par rapport à l'euro, cotation des cryptos, faillites par pays, index de corruption, notation attribuée par les agences de notation par pays, PIB par pays, … Nous avons plus de 200 services qui sont définis pour faire tourner la radio. Les services sont utilisés partout !
Objectif de cet article
Nous allons finaliser la toute première version de notre API, une API de données économiques exposant 3 services. Nous allons voir que c'est excessivment simple.
Ensuite, une fois cette étape atteinte, dans un prochain article, nous irons crescendo dans la difficulté en ajoutant un quatrième service qui, cette fois, et ce sera là toute la nouveauté, nécessitera le passage de paramètre(s).
L'ajout des deux services manquants
Finalement, cet ajout est une simple affaire de copier-coller, puis de modifications mineures. Voici l'état de notre YAML :
openapi: 3.1.0 info: version: 0.0.1 title: TRQL Radio economics-related services description: First version of the TRQLEconomics API featuring 3 services contact: email: pb@latosensu.be license: name: CC BY-SA 4.0 DEED Attribution-ShareAlike 4.0 International url: https://creativecommons.org/licenses/by-sa/4.0/ termsOfService: https://www.trql.fm/tos/ servers: - url: http://www.trql.fm/vaesoli! description: Production Server paths: /?bankruptcies: get: responses: '200': description: List of bankruptcies per country
Voici ce qu'il devient :
openapi: 3.1.0 info: version: 0.0.1 title: TRQL Radio economics-related services description: First version of the TRQLEconomics API featuring 3 services contact: email: pb@latosensu.be license: name: CC BY-SA 4.0 DEED Attribution-ShareAlike 4.0 International url: https://creativecommons.org/licenses/by-sa/4.0/ termsOfService: https://www.trql.fm/tos/ servers: - url: http://www.trql.fm/vaesoli! description: Production Server paths: /?bankruptcies: get: responses: '200': description: List of bank ruptcies per country /?corruption: get: responses: '200': description: List of corruption index per country /?currencies: get: responses: '200': description: 9 conversion rates of currencies compared to EURO
Et voici ce que Swaggerhub nous propose en partie UI :

Ne boudons pas notre plaisir ! Avec ce genre de fonctionnalité, nous disposons d'une console à services ! Il suffirait de faire le pont entre notre catalogue de services et ce YAML pour disposer d'une solution quasi complète. Et … vous vous en doutez maintenant, c'est EXACTEMENT la ligne sur laquelle je vous conduit car, au surplus, nous disposons là aussi de notre embryon d'automatisation de notre pipeline de déploiement cher à DevOps ! Je vais arrêter de m'emballer. Pied sur le frein !
Petit mot pour le Product Owner, petit mot pour le Scrum Master, petit mot pour le Project Manager , et petit mot pour le Testeur
Cette série d'articles sur l'écriture des services et microservices vous est destinée. Les gens qui sont dans la technique connaissent cela par cœur.
Si je dis que c'est fait pour vous, c'est parce que la compréhension du Comment ça marche vous apportera un éclairage sur la nature du développement moderne, du moins ses principes. Cela vous permettra de juger de la pertinence des solutions techniques, surtout si vous consultez le ou les architecte(s) et autre(s) leader(s) technique(s), mais aussi de juger de l'adéquation entre ce qui est demandé et les estimations qui vous sont soumises. Pour le testeur, voilà de quoi commencer à tester les services, et même de corriger/participer à la définition des services, de telle sorte que les spécifications soient, elles aussi, de grande qualité. J'ai la faiblesse de penser que cela fait de vous des personnes mieux éclairées, si tant est que ce soit possible, pour le bien des organisations pour lesquelles vous exercez votre métier.
Développons plus avant les 3 services dont nous disposons
Commençons par la réponse. Comme vous vous en souvenez peut-être,
toutes les réponses de nos services sont composées d'un
prolog
(meta data concernant le service) et
d'un payload
(le corps principal de la réponse).
Dans notre cas, c'est invariable de telle sorte que nous pouvons
définir le même type de retour pour chaque service, un retour qui se
fait est au format JSON.
Le retour est donc un objet JSON composé de … 2 objets, le
prolog
et le payload
.
Voyons comment mentionner cela pour le service
bankruptcies
sans entrer dans le detail, ni du
prolog
, ni du payload
:
schema object
Je vais vous montrer directement comment renseigner cette structure du retour :
paths:
/?bankruptcies:
get:
responses:
'200':
description: List of bankruptcies per country
content:
application/json: # Le retour est formaté en JSON
schema: # À détailler
type: object # L'objet de retour englobant le prolog et le payload
properties:
prolog: # L'objet prolog qu'on devra détailler plus avant
type: object
payload: # L'objet payload qu'on devra détailler plus avant
type: object
L'objet schema peut être consulté en ligne.
Trois propriétés de cet objet nous intéressent au premier chef :
type
: type du schéma, dans notre cas, un objet (le retour JSON est un objet qui en inclut 2 autres)description
: Description du retourproperties
: des propriétés imbriquées définies elles-mêmes comme des schémas
Ajoutons une description au schéma de retour :
paths: /?bankruptcies: get: responses: '200': description: List of bankruptcies per country content: application/json: # Retour en JSON schema: # À détailler ultérieurement type: object # L'objet de retour englobant le prolog et le payload description: Le retour est un objet composé de deux objets, prolog et payload. properties: prolog: # L'objet prolog qu'on devra détailler plus avant type: object payload: # L'objet payload qu'on devra détailler plus avant type: object

C'est ici que les Romains s'empoignèrent : précisions à présent les propriétés ! Afin
de montrer comment cela fonctionne et de minimiser le code YAML à considérer, je ne
vais m'employer qu'à définir le payload
car il est bien
plus simple que le prolog
.
paths: /?bankruptcies: get: responses: '200': description: List of bankruptcies per country content: application/json: # Retour en JSON schema: # À détailler ultérieurement type: object # L'objet de retour englobant le prolog et le payload description: Le retour est un objet composé de deux objets, prolog et payload. properties: prolog: # L'objet prolog qu'on devra détailler plus avant type: object payload: # L'objet payload qu'on devra détailler plus avant type: object properties: entries: # Seule propriété de l'objet payload type: array # entries est un tableau d'entrées

On pourrait — et nous le ferons plus tard — détailler le
tableau entries
.
Pourquoi vous disais-je que c'était ici que les Romains se
mettaient à s'empoigner ? Tout simplement parce que l'objet
prolog
est beaucoup plus détaillé et donc,
infiniment plus long à documenter. Faisons-le pour le service
bankruptcies
seul !
paths: /?bankruptcies: get: responses: '200': description: List of bankruptcies per country content: application/json: # Retour en JSON schema: # À détailler ultérieurement type: object # L'objet de retour englobant le prolog et le payload description: Le retour est un objet composé de deux objets, prolog et payload properties: prolog: type: object description: metadata of the service properties: service: type: string domain: type: string line: type: integer performance: type: number error: type: integer messages: type: array datetime: type: string cached: type: boolean cacheDateTime: type: string ttl: type: integer callDateTime: type: integer copyright: type: string disclaimer: type: string payload: type: object description: véritable charge utile du retour (la cœur de la réponse) properties: entries: type: array # entries est un tableau d'entrées
Si on devait répercuter cela sur tous nos services, on
alourdirait considérablement la taille du YAML ce qui peut rapidement
devenir peu commode. De plus, si nous devions modifier la définition
du prolog
par exemple, on risque de faire des
fautes de frappe, oublier l'un ou l'autre service, etc. Quand on n'a
que 3 services comme dans notre cas, passe encore, mais lorsque vous
en avez 63 comme dans le cas de TRQL Radio (services liés à des données
économiques), cela devient carrément rédhibitoire !
Heureusement, OpenAPI a prévu le coup ! Nous allons passer par une définition générale et nous ferons référence à cette définition générale dans chaque service; nous allons utiliser … les composants !
Définir un composant
Les composants de OpenAPI sont une manière de standardiser ce que vos services utiliseront et ré-éutiliseront. Cela réduit considérablement le travail tout en améliorant la qualité de nos spécifications et c'est notamment pour cette raison que je m'adresse aux Product Owners, aux Scrum Masters, aux Project Managers et aux Testeurs parce que tous peuvent contribuer à réduire le travail (parfois en y prenant part), à comprendre ce qui se passe en arrière-plan, et à améliorer la qualité finale du tout, notamment par une révision approfondie des spécifications fournies pour chaque service. Tout profit pour vos projets/produits et pour l'entreprise dans laquelle vous œuvrez.
La doc des composants est disponible sur le GitHub de OpenAPI.
Voyons tout de suite comment définir des composants qui sont des schémas puisque c'est, au demeurant, ce qui nous intéresse au premier chef. Commençons par notre fameux prolog que nous allons inclure dans notre YAML au même niveau que l'objet paths:
components: schemas: prolog: type: object description: metadonnées du service properties: service: type: string domain: type: string line: type: integer performance: type: number error: type: integer messages: type: array datetime: type: string cached: type: integer cacheDateTime: type: string ttl: type: integer callDateTime: type: integer copyright: type: string disclaimer: type: string
Maintenant que nous avons défini notre schéma "prolog", voyons
comment y faire référence dans le service
bankruptcies
…
paths: /?bankruptcies: get: responses: '200': description: List of bankruptcies per country content: application/json: # Retour en JSON schema: # À détailler ultérieurement type: object # L'objet de retour englobant le prolog et le payload description: Le retour est un objet composé de deux objets, prolog et payload properties: prolog: $ref: "#/components/schemas/prolog" payload: type: object description: véritable charge utile du retour (la cœur de la réponse) properties: entries: type: array # entries est un tableau d'entrées
Et le tour est joué ! On a une définition globale à laquelle on peut faire référence dans chaque service, on ne perd pas de temps à définir et redéfinir la même chose, on peut modifier la définition et voir nos modifications se répercuter sur tous les services où nous y faisons appel et tout le monde dans le projet peut partager la même vision commune du fonctionnement des services.
Puisque tel est le cas, faisons la même chose pour le
payload
:
components: schemas: prolog: type: object description: metadonnées du service properties: service: type: string domain: type: string line: type: integer performance: type: number error: type: integer messages: type: array datetime: type: string cached: type: integer cacheDateTime: type: string ttl: type: integer callDateTime: type: integer copyright: type: string disclaimer: type: string payload: type: object description: véritable charge utile du retour (la cœur de la réponse) properties: entries: type: array # entries est un tableau d'entrées

bankruptcies
Généralisation aux 3 services et YAML final (pour cet article)
openapi: 3.1.0 info: version: 0.0.1 title: TRQL Radio economics-related services description: First version of the TRQLEconomics API featuring 3 services contact: email: pb@latosensu.be license: name: CC BY-SA 4.0 DEED Attribution-ShareAlike 4.0 International url: https://creativecommons.org/licenses/by-sa/4.0/ termsOfService: https://www.trql.fm/tos/ servers: - url: http://www.trql.fm/vaesoli! description: Production Server components: schemas: prolog: type: object description: metadonnées du service properties: service: type: string domain: type: string line: type: integer performance: type: number error: type: integer messages: type: array datetime: type: string cached: type: integer cacheDateTime: type: string ttl: type: integer callDateTime: type: integer copyright: type: string disclaimer: type: string payload: type: object description: véritable charge utile du retour (la cœur de la réponse) properties: entries: type: array # entries est un tableau d'entrées paths: /?bankruptcies: get: responses: '200': description: List of bankruptcies per country content: application/json: # Retour en JSON schema: type: object # L'objet de retour englobant le prolog et le payload description: Le retour est un objet composé de deux objets, prolog et payload properties: prolog: $ref: "#/components/schemas/prolog" payload: $ref: "#/components/schemas/payload" /?corruption: get: responses: '200': description: List of corruption index per country content: application/json: # Retour en JSON schema: type: object # L'objet de retour englobant le prolog et le payload description: Le retour est un objet composé de deux objets, prolog et payload properties: prolog: $ref: "#/components/schemas/prolog" payload: $ref: "#/components/schemas/payload" /?currencies: get: responses: '200': description: 9 conversion rates of currencies compared to EURO content: application/json: # Retour en JSON schema: type: object # L'objet de retour englobant le prolog et le payload description: Le retour est un objet composé de deux objets, prolog et payload properties: properties: prolog: $ref: "#/components/schemas/prolog" payload: $ref: "#/components/schemas/payload"
Conclusion
Nos 3 services partagent la même structure; ils sont tous définis
correctement et sont utilisables. Le prochain article s'attachera à
définir des paramètres et pour illustrer leur utilisation nous
allons ajouter un quatrième service, mercator
,
qui nous donnera une série d'informations de géolocalisation pour
une latitude/longitude données (paramètres en question).
À très bientôt et, surtout, pas de complication !