GraphQL : interfaçage avec OSB

Présentation

Dans ce 3ème et dernier article consacré au langage d’API GraphQL, nous allons voir comment interfacer GraphQL avec Oracle Service Bus (OSB).
La suite SOA d’Oracle utilise le protocole SOAP de manière standard mais n’implémente pas du tout GraphQL. L’objectif est de créer une service qui permettra d’appeler les requêtes GraphQL via l’intermédiaire d’un WebService (WS) SOAP.

 

Implémentation technique

Traduction des requêtes

Pour exécuter une requête SOAP, il faut d’abord choisir une opération. Or, notre API GraphQL permet d’effectuer 5 actions (lire, créer, modifier, supprimer, s’abonner) sur 4 objets (client, adresse, bon de commande et article). Du coup, on peut associer 20 actions en SOAP (lire un client, créer un article, …).
Pour cela, on crée un DVM qui, pour chaque opération SOAP, va associer un requête GraphQL :

DVM requêtes
DVM requêtes

Note : Comme SOAP ne permet pas de choisir les champs à récupérer (contrairement à GraphQL), nos requêtes GraphQL seront écrites de façon à ramener le maximum de champs possibles.
Et on peut, en plus, initialiser le WSDL avec nos opérations :

WSDL opérations
WSDL opérations

Traduction des paramètres/réponses

SOAP utilise le format de données XML là où GraphQL utilise JSON. OSB permet de passer d’un format à l’autre via les nXSD.
Nous prendrons comme exemple la lecture d’une adresse, mais le principe sera le même pour toutes les opérations.

Paramètres

On commence par écrire un exemple de paramètres de requête dans un fichier JSON nommé « parameters » :

requête format JSON
requête format JSON

Note : Tous les paramètres possibles sont écrits dans l’exemple. En conditions d’utilisation réelle, on pourra ne passer que les paramètres utiles.
Ensuite, on crée la nXSD, la transformation en XML :

nXSD requête
nXSD requête

Enfin, pour préparer les tests, on crée un exemple de paramètres au format XML tel que SOAP l’attendra :

exemple requête XML
exemple requête XML

Réponses

Pour les réponses, on crée aussi un exemple de JSON pour le traduire en nXSD. Les principes sont les mêmes, bien que les schémas soient plus complexes.

JSON réponse
JSON réponse
nXSD réponse
nXSD réponse

Erreurs

GraphQL remonte les erreurs comme une simple liste de texte, avec une erreur par ligne.
On peut donc créer un simple format XSD pour ce cas (pas besoin de passer par un JSON et une nXSD, on écrit directement le fichier XSD) :

XSD erreur
XSD erreur

Schéma WSDL SOAP

Il est donc possible de finir d’écrire le WSDL en associant les messages aux nXSD :

  • message d’entrée : nXSD paramètre
  • message de sortie : nXSD réponse
  • message d’erreur : nXSD d’erreur
messages WSDL
messages WSDL

Points d’entrée sortie

Entrée SOAP

Maintenant que le WSDL est fait, on peut exposer le proxy comme point d’entrée SOAP :

proxy SOAP
proxy SOAP

Sortie HTTP

Pour la sortie et pour rester cohérent avec l’article précédent, nous utiliserons un business HTTP, en passant les données via le verbe POST et au format texte. L’URL sera statique et référencera le point d’entrée du serveur GraphQL.

business HTTP
business HTTP

Assemblage du flux

Maintenant que nous avons tous les formats et les points d’E/S, il ne reste plus qu’à tout lier à travers 2 pipelines :

  • dummyOsbGraphQLClient : réception du message SOAP
  • commonGraphQLClient : appel GraphQL
flux général
flux général

Nous prendrons comme exemple la lecture d’adresses, mais toutes les autres opérations suivront la même logique.

Réception du message SOAP

Ce pipeline se place juste après la réception de la requête SOAP et permet d’y associer un couple requête/ressource.
Une fois ce couple associé, on appelle le pipeline suivant pour envoyer la requête GraphQL.

pipeline SOAP
pipeline SOAP

Appel GraphQL

Ce pipeline contient toute l’intelligence de l’interface SOAP/GraphQL.
Il prend en entrée le couple requête/ressource défini ci-dessus.

pipeline GraphQL
pipeline GraphQL
  1. Recherche de la requête dans le DVM (à partir du couple requête/ressource).

    recherche DVM de la requête
    Recherche DVM de la requête
  2. Toujours à partir du couple requête/ressource, transformation des paramètres de XML(SOAP) vers JSON(GraphQL).

    transformation des paramètres
    Transformation des paramètres
  3. A partir de la requête et des paramètres, on crée le body attendu par le service GraphQL (verbe POST).

    Contenu de la requête GraphQL
    Contenu de la requête GraphQL
  4. On appelle le service GraphQL.

    appel GraphQL
    Appel GraphQL
  5. Toujours à partir du couple requête/ressource, transformation de la réponse de JSON(GraphQL) vers XML(SOAP).

    transformation de la réponse GraphQL
    Transformation de la réponse GraphQL
  6. Si besoin, renvoyer les erreurs.

    interception des erreurs
    Interception des erreurs

 

Tests

Maintenant, nous pouvons tester notre interface via la console OSB.
Comme pour les exemples précédents, nous nous limiterons à une lecture d’adresse mais la logique pourra être généralisée.
Enfin, à côté des JSON et nXSD, des exemples de requêtes sont fournis avec les sources.

Retour conforme

On lance la console de test du proxy « dummyOsbGraphQLClient » (associé au service SOAP).
Ensuite, on saisit l’opération et la requête puis on exécute :

Test requête valide
Test requête valide

On peut alors voir que la réponse est conforme au schéma :

test réponse valide
Test réponse valide

Retour en erreur

Si on supprime un paramètre obligatoire, on reçoit bien une erreur :

test erreur
Test erreur

 

Conclusion

Même si la suite SOA d’Oracle ne propose pas d’implémentation pour le langage d’API GraphQL, il est possible de contourner le problème.
En effet, GraphQL expose clairement des requêtes sur des objets de base. Il est donc possible de faire une table de correspondance entre une action SOAP et un couple requête/ressource GraphQL.
De plus, GraphQL est un language fortement typé, ce qui est parfait pour établir les messages dans le WSDL SOAP.
Il est donc possible, avec OSB, de faire une interface de traduction SAOP<->GraphQL qui pourra être utilisée par d’autres composant SOA.

 

Références