Configurer un traitement Import depuis une API JSON
Le plugin Import depuis une API JSON interroge une API HTTP qui répond en JSON, et transforme le résultat en un jeu de données de la plateforme. Ce cours le configure pour récupérer l'agenda public OpenAgenda de Bordeaux Métropole : une source protégée par une clé, et dont la réponse impose de naviguer dans des champs imbriqués — deux mécaniques à comprendre avant de remplir le formulaire.
💡 Ce cours ne décrit que ce qui est propre à ce plugin. Pour la mécanique commune à tous les traitements — créer un traitement, choisir l'action, planifier, suivre les exécutions, gérer les permissions et les notifications — consultez le cours Programmer des mises à jour automatiques de données.
1. Explorer l'API source
1.1 Obtenir une clé OpenAgenda
L'API OpenAgenda nécessite une clé : sans elle, chaque appel échoue avec une erreur 403. Créez un compte sur openagenda.com, puis ouvrez Paramètres → Clés API pour la récupérer. Elle s'utilise en l'ajoutant à l'en-tête HTTP key de chaque requête — c'est justement ce que permet la méthode d'authentification API key du traitement, configurée plus bas.
Chaque agenda a son propre identifiant dans l'URL — ici bordeaux-metropole : remplacez-le par le vôtre pour interroger un autre agenda OpenAgenda.
1.2 Repérer la structure de la réponse
Tout le paramétrage du plugin consiste à décrire des chemins dans la réponse JSON. Il faut donc commencer par la regarder. Un appel à l'API renvoie un objet englobant : le nombre total de résultats, puis le tableau des évènements sous la clé events [1] — c'est ce chemin qu'il faudra indiquer comme chemin des résultats.
Chaque évènement mélange trois formes de données, et c'est cette diversité qui rend l'exemple intéressant :
- des objets imbriqués — le titre n'est pas une chaîne mais un objet par langue [2] (OpenAgenda est multilingue), et le lieu regroupe nom, ville et coordonnées sous
location[4] ; - un tableau de chaînes — les mots-clés [3], sous
keywords.fr; - des tableaux d'objets — les liens [5], et surtout les séances [6] : un même évènement peut se tenir plusieurs jours, chaque créneau ayant son début et sa fin sous
timings.
Les champs keywords, links et timings ne sont renvoyés que si la requête porte le paramètre detailed=1 — d'où sa présence dans l'URL configurée ci-dessous.
2. Configurer le traitement
La configuration propre au plugin se répartit sur deux onglets : Source des données (où aller chercher le JSON) et Champs à récupérer (comment le transformer en colonnes).
2.1 Source des données
Renseignez l'URL de l'API [1] : https://api.openagenda.com/v2/agendas/bordeaux-metropole/events?detailed=1. Elle ne contient aucun secret, elle reste donc lisible et partageable.
Choisissez ensuite la méthode d'authentification [2] : API key. Deux champs apparaissent : la Clé [3], le nom de l'en-tête HTTP attendu par la source (key pour OpenAgenda), et la Valeur [4], la clé elle-même — un champ de type mot de passe, jamais affiché en clair. Cela permet de documenter et de partager la configuration sans jamais exposer le secret.
Reste la pagination [5]. La plupart des API ne renvoient qu'une page de résultats à la fois : sans pagination, le traitement n'importera que cette première page. Le plugin propose trois méthodes.
[1] Pas de pagination. Un seul appel, une seule page. C'est le bon choix quand la source renvoie tout d'un coup (petit fichier JSON, API de configuration), ou pour un premier essai — c'est ce que fait ce cours, qui se contente des 20 évènements de la page par défaut.
[2] Extraire l'URL de la page suivante depuis la donnée. Pour les API qui renvoient elles-mêmes le lien de la page suivante dans leur réponse — le style HAL / JSON:API, très répandu. Indiquez le chemin vers la page suivante dans le JSON (par exemple next) ; le traitement suit ce lien de proche en proche jusqu'à ce qu'il soit absent. Les champs nom du paramètre de type limit et nombre d'éléments par page (1000 par défaut) permettent en plus de demander de grandes pages, pour limiter le nombre d'appels.
[3] Paramètres dans l'URL. Pour les API qui ne fournissent aucun lien mais acceptent un couple de paramètres de décalage et de taille — le cas le plus courant, et celui d'OpenAgenda (from et size). Renseignez le nom du paramètre de type offset (offset par défaut, souvent from ou skip) et le nom du paramètre de type limit (size, limit, take…). Par défaut, le décalage est incrémenté du nombre de lignes déjà lues ; si votre API compte en numéros de page et non en nombre d'éléments, cochez Offset en nombre de pages, qui l'incrémente de 1 à chaque appel.
En résumé : la réponse contient un lien vers la suite → méthode [2] ; il faut fabriquer soi-même l'URL de la page suivante → méthode [3] ; tout tient en un appel → méthode [1]. En cas de doute, essayez la source dans un navigateur et regardez ce que contient la réponse.
2.2 Champs à récupérer
Le second onglet décrit la transformation du JSON en tableau. Le chemin des résultats [1] indique où se trouve, dans la réponse, le tableau à parcourir : events, comme repéré plus haut. Une ligne du jeu de données sera produite par élément de ce tableau. Si l'API renvoyait directement un tableau à la racine, ce champ resterait vide.
Chaque entrée de la liste Champs à récupérer associe ensuite un identifiant de colonne — le nom qu'aura la colonne dans le jeu de données — à un chemin de la colonne, évalué dans l'objet de chaque évènement :
| Colonne | Chemin | Ce que ça lit |
|---|---|---|
| titre | title.fr |
une propriété imbriquée [2] |
| lieu | location.name |
idem |
| ville | location.city |
idem |
| latitude | location.latitude |
idem |
| longitude | location.longitude |
idem |
| mots_cles | keywords.fr |
un tableau de chaînes [3] |
| liens | links[].link |
une propriété dans un tableau d'objets [4] |
2.3 Écrire un chemin
Deux notations seulement, mais il faut les distinguer.
Le point descend dans les objets. location.city lit la propriété city de l'objet location. Le .fr de title.fr n'est pas décoratif : sans lui, le traitement chercherait une valeur directement sous title, où il n'y a qu'un objet par langue, et la colonne resterait vide.
Les crochets traversent un tableau d'objets. links[].link signifie : pour chaque élément du tableau links, prends sa propriété link. Les valeurs obtenues ne créent pas de lignes supplémentaires : elles sont concaténées dans une seule cellule.
C'est là qu'intervient le champ Séparateur pour les tableaux, en bas de l'onglet (; par défaut) : c'est le caractère qui joint ces valeurs multiples. Il n'a de sens que pour les chemins qui ramènent plusieurs valeurs — ceux qui utilisent [], et ceux qui pointent directement un tableau de chaînes. Choisissez un caractère qui n'apparaît pas dans les données elles-mêmes.
Deux pièges, vérifiés à l'exécution :
- un tableau de chaînes se lit sans crochets. Pour les mots-clés, le chemin est
keywords.fr, paskeywords.fr[]— le tableau est déjà la valeur finale, il n'y a rien à traverser. Avec les crochets, la colonne ressort vide ; - les crochets ne se posent que sur un vrai tableau. Écrire
keywords[].fralors quekeywordsest un objet fait échouer l'exécution.
En cas de doute, comparez le chemin à la réponse JSON de la section 1.2 : [] se place exactement là où vous voyez un [ suivi de { dans le JSON.
2.4 Données en profondeur d'un tableau
La concaténation convient aux mots-clés ou aux liens, mais pas aux séances : un évènement qui se tient les 9 et 10 juillet devrait produire deux lignes, chacune avec sa date, pour être exploitable dans un calendrier ou une recherche par date. C'est le rôle de la carte Données en profondeur d'un tableau, en bas de l'onglet.
Elle prend un chemin [1] vers un tableau imbriqué — ici timings — puis rouvre, à l'intérieur, une liste de champs à récupérer [2] dont les chemins sont évalués relativement à chaque élément de ce tableau : begin et end, et non timings.begin.
Ce que cela produit, mesuré sur une exécution réelle : le traitement émet une ligne par élément du tableau imbriqué, et non une ligne par élément du tableau de résultats. Les colonnes du niveau parent (titre, lieu, ville, mots-clés…) sont recopiées à l'identique sur chacune de ces lignes, et les colonnes du bloc imbriqué s'ajoutent à côté. Le résultat reste un seul tableau plat : 20 évènements totalisant 28 séances ont donné 28 lignes et 9 colonnes. Un évènement sans séance ni tableau timings produit malgré tout sa ligne, colonnes imbriquées vides.
La carte est récursive [3] : à l'intérieur d'un bloc imbriqué, un nouveau bloc Données en profondeur d'un tableau est proposé, sans limite de profondeur. On peut ainsi aplatir un JSON à plusieurs niveaux de tableaux — en gardant en tête que le nombre de lignes se multiplie à chaque niveau.
⚠️ Choisissez donc bien le tableau à déplier : le dépliage définit la granularité d'une ligne du jeu de données. Ici, une ligne n'est plus un évènement mais une séance d'évènement — ce que reflète le titre donné au jeu produit. Si vous vouliez au contraire un enregistrement par évènement, laissez la carte vide et lisez la première date via un chemin simple (firstTiming.begin).
3. Résultat
L'exécution produit un jeu de données de 28 enregistrements [1] et 9 colonnes [2] à partir des 20 évènements de la page. Les deux petites icônes devant mots_cles et liens signalent des colonnes multivaluées : déclarez le séparateur sur ces colonnes dans l'onglet Schéma pour que la plateforme les traite comme des listes plutôt que comme du texte.
Dans les données, l'effet du dépliage est visible directement : Tour de France [1] et Le Belem fait escale à Bordeaux [2] occupent chacun deux lignes, identiques sauf pour debut et fin. Les mots-clés [3] s'affichent en valeurs distinctes grâce au séparateur.
Si la plateforme ne reconnaît pas automatiquement les colonnes latitude et longitude comme des coordonnées géographiques, associez-les au concept correspondant depuis l'onglet Schéma du jeu de données : l'onglet Carte affiche alors chaque évènement à sa position.
Si vous avez des remarques sur ce cours, n'hésitez pas à nous les communiquer.