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
- Apache Hop 2.19.0 (version stable publiée le 17 août 2026), qui requiert Java 21.
- Un projet Hop configuré, avec un environnement permettant de définir des variables.
- Une API REST accessible et sa documentation : URL de base, mode d’authentification, mécanisme de pagination.
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 :
- Base URL : la racine de l’API, à laquelle les transforms ajouteront un chemin relatif.
- Test URL : une URL complète réservée au test de connexion.
- Authentication type : No Auth, API Key (nom de l’en-tête, préfixe optionnel, valeur), Basic (identifiant, mot de passe, option Preemptive), Bearer (jeton) ou OAuth 2 (Token URL, Grant type, Client ID, Client secret, Refresh token, Scope).
- Les réglages SSL et certificats clients : trust store, key store, alias de certificat, option d’ignorance des erreurs SSL.
- Les réglages avancés : Connect timeout, Read timeout, et l’ensemble des paramètres de proxy.
- La stratégie de pagination, détaillée plus loin.
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 :
- HTTP method : GET, POST, PUT, DELETE, HEAD, OPTIONS, PATCH, ou un verbe personnalisé. La méthode peut aussi venir d’un champ du flux.
- Application type : JSON pour une API moderne. Ce choix conditionne l’interprétation du corps et la possibilité de découper le résultat.
- Result fieldname : le champ de sortie qui recevra le corps de la réponse.
- HTTP status code fieldname, Response time fieldname et Response header fieldname : trois champs facultatifs, et pourtant les plus utiles en exploitation. Le code HTTP permet de router les échecs, le temps de réponse alimente une métrique de supervision, les en-têtes arrivent sous forme d’objet JSON.
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
- REST Client — documentation complète du transform, onglet par onglet.
- REST connection — tous les champs du type de métadonnée, dont les stratégies de pagination.
- JSON Input — options de lecture et expressions de chemin.
- Variables — syntaxe et niveaux de définition.
- Metadata Types — vue d’ensemble des métadonnées d’un projet Hop.
- Hop Run — options de la ligne de commande.