Vos pipelines savent lire des bases de données, des fichiers plats et des fichiers Excel. Puis arrive la demande qui change la nature du travail : « récupère les commandes du CRM, il y a une API ». Et là, la mécanique habituelle ne s’applique plus. L’API renvoie du JSON imbriqué, elle réclame un jeton dans un en-tête, elle limite chaque réponse à cinquante enregistrements et vous impose de suivre un curseur pour obtenir les suivants. La tentation est forte d’écrire un script à côté du pipeline, et de voir la chaîne se scinder en deux morceaux qui ne partagent ni journalisation, ni variables, ni gestion d’erreurs.

Apache Hop traite ce cas sans sortir du pipeline. Le transform REST Client gère les appels HTTP, les tentatives de reprise et la boucle de pagination, tandis que le type de métadonnée REST Connection centralise l’URL de base et l’authentification. Cet article décrit la mise en place complète, de la déclaration de la connexion à l’aplatissement du JSON.

Prérequis

1. Déclarer la connexion plutôt que l’URL

La première erreur consiste à saisir l’URL complète et le jeton directement dans le transform. Chaque nouveau pipeline duplique alors la configuration, et le passage de la recette à la production demande une retouche manuelle de chaque fichier. Hop propose un type de métadonnée dédié : REST Connection. Comme toutes les métadonnées de Hop, elle est enregistrée au format JSON dans un sous-dossier du dossier metadata du projet, donc versionnable avec le reste du code.

Une REST Connection regroupe :

Les secrets n’ont rien à faire dans ce fichier. Utilisez la syntaxe de variable de Hop et définissez la valeur au niveau de l’environnement :

Authentication type : Bearer
Bearer token       : ${CRM_API_TOKEN}
Base URL           : ${CRM_API_BASE_URL}

Le même pipeline s’exécute ainsi en recette et en production sans modification, seule la configuration d’environnement change.

2. Le premier appel

Un transform REST Client consomme une ligne d’entrée par appel. Pour un appel unique, un transform Row Generator avec Limit à 1 suffit à amorcer le flux.

Dans l’onglet General du REST Client, sélectionnez la REST Connection créée. Point important : lorsqu’une connexion est sélectionnée, l’URL saisie est interprétée comme un chemin relatif à l’URL de base. Les onglets Authentication et SSL sont alors grisés, la connexion fournissant l’authentification, le proxy, les réglages SSL et les délais d’attente pour l’ensemble du client.

Renseignez ensuite :

L’onglet Headers construit les en-têtes à partir de champs du flux entrant, avec un bouton Get fields pour les récupérer. Attention à la règle de priorité : un en-tête défini dans cet onglet écrase celui de même nom défini dans la REST Connection. L’onglet Query Parameters fonctionne de la même manière pour les paramètres ajoutés après le ?.

3. Transformer la réponse en lignes

À ce stade, une seule ligne contient tout le JSON. Deux approches permettent de l’aplatir.

La première est interne au REST Client : le champ Optional result split JsonPath/XPath, dans l’onglet Pagination. Lorsqu’il est renseigné et que l’Application type vaut JSON ou XML, Hop émet une ligne de sortie par correspondance au lieu d’une ligne unique contenant tout le corps. Pour un tableau racine, l’expression est :

$[*]

La seconde approche repose sur le transform JSON Input, plus adapté dès que la structure est imbriquée. Cochez Source is from a previous transform, désignez le champ contenant la réponse via Select field, puis décrivez les colonnes dans l’onglet Fields avec un couple Name / Path et un type :

Name          Path                        Type
order_id      $.data[*].id                Integer
customer      $.data[*].customer.name     String
amount        $.data[*].total_amount      Number
created_at    $.data[*].created_at        Date

Deux options de l’onglet Content méritent une attention particulière lorsque les API renvoient des champs absents selon les enregistrements : Ignore missing path évite l’échec du pipeline sur un chemin introuvable, et Default path leaf to null produit une valeur nulle plutôt qu’une erreur.

4. La pagination, sans boucle manuelle

C’est ici que Hop apporte le gain le plus net. La stratégie de pagination se déclare dans la REST Connection, et le transform se charge d’enchaîner les appels. Les stratégies disponibles couvrent les conventions les plus répandues.

Stratégie Usage
NONE Désactive la pagination.
LINK_HEADER Suit les liens rel="next" de l’en-tête HTTP.
OFFSET_LIMIT Incrémente un décalage, avec les paramètres offset et limit par défaut.
PAGE_NUMBER Incrémente un numéro de page.
CURSOR Transmet un curseur en paramètre de requête.
BODY_CURSOR Extrait le curseur du corps de la réponse via une expression JsonPath ou XPath.
HEADER_CURSOR Extrait le curseur d’un en-tête de réponse.
BODY_NEXT_URL Lit l’URL de la page suivante dans le corps de la réponse.

Selon la stratégie retenue, la connexion expose le nom du paramètre de page ou de curseur, le nom du paramètre de décalage, le nom du paramètre de taille de lot, la taille de lot par défaut, et les expressions JsonPath ou XPath permettant de localiser le curseur ou l’URL suivante.

Côté transform, l’onglet Pagination active le mécanisme avec Enable pagination loop for incoming rows : Hop effectue alors plusieurs requêtes HTTP par ligne d’entrée jusqu’à épuisement des pages. Le champ Maximum page requests per input row plafonne ce nombre d’itérations ; laissé vide ou à 0, un garde-fou intégré de 256 requêtes s’applique. La boucle s’interrompe lorsqu’il n’y a plus de page suivante, en cas de code HTTP non 2xx, à l’atteinte du plafond, ou — pour la stratégie LINK_HEADER — lorsqu’une URL déjà appelée se présente de nouveau.

Le projet de samples livré avec Hop contient un exemple complet, rest-client-github-releases-loop.hpl, qui liste les versions publiées d’Apache Hop sur GitHub en LINK_HEADER avec per_page=5 et découpe le résultat avec $[*].

5. Fiabiliser l’appel

Une API distante échoue, ponctuellement et sans prévenir. L’onglet Retry Option du REST Client traite ce cas sans logique maison : Retry times fixe le nombre de tentatives supplémentaires après le premier échec, Retry delay(ms) le délai de base avant la première reprise (200 ms par défaut), Retry HTTP status codes la liste des codes déclenchant une reprise, et Retry HTTP methods les méthodes concernées.

Complétez par des délais d’attente explicites — Connection timeout et Read timeout, exprimés en millisecondes — pour éviter qu’un pipeline planifié ne reste bloqué indéfiniment. Enfin, pour les API qui diffusent leurs résultats au fil de l’eau, l’onglet Streaming Result permet d’émettre une ligne par enregistrement pendant la réception, aux formats NDJSON ou SSE.

6. Exécuter en dehors de l’interface

Le pipeline s’exécute ensuite comme n’importe quel autre, le jeton étant résolu par l’environnement :

hop-run.sh -j mon-projet -e production -r local \
  -f ${PROJECT_HOME}/pipelines/extraction-crm.hpl

Ce que vous avez gagné

L’extraction depuis l’API vit désormais dans le même pipeline que le reste de la chaîne : même journalisation, mêmes variables, même orchestration par workflow, même intégration continue. L’authentification est déclarée une seule fois, dans un objet versionné et indépendant de l’environnement. La pagination, la reprise sur erreur et les délais d’attente sont de la configuration, non du code. Et le jour où l’API change de mécanisme de pagination, la correction se fait en un point unique.

Pour aller plus loin

Un projet Apache Hop ? Parlons-en.

Devis et programme détaillé sous 48 h ouvrées. Financement OPCO accompagné.

Demander un devis