Dans la #SynalTeam, il y a toutes sortes de spécialistes. Tableau, Js, Talend, Architecture…tout un petit monde qui évolue joyeusement dans nos bureaux pour le plus grand plaisir de nos clients. Et parfois, ce petit monde est appelé à travailler ensemble sur des projets internes !
Notre histoire se passe alors que nous effectuions un développement pour un projet encore tenu secret, impliquant l’utilisation de l’API Rest Tableau pour afficher des workbooks, migrer des workbooks, faire de l’edit de connexion etc…(Nous n’en dirons pas plus pour le moment, ce n’est pas tout à fait sec, mais promis, on finira par vous expliquer !)
Alors que nous avancions dans nos développements, nous n’avions pas rencontré de difficultés majeures pour tout ce qui est GET ou UPDATE avec l’API.
Mais quand nous avons voulu faire un POST, ça n’a pas été la même histoire. Notre objectif était de migrer des workbooks et/ ou des data sources mais, malgré le fait que nous nous en tenions aux recommandations de la documentation de Tableau sur on API (cf ci-dessous), RIEN ne passait. Echec cuisant.
Petit explication, il y a deux manières d’utiliser cet appel :
- Publier le workbook en une seule requête, on copie/colle le contenu du workbook à la place de “content of workbook file”. Cela fonctionne en une seule requête si le contenu du workbook fait moins 64 Mo.
- Publier un workbook en multi-parts : il faut d’abord initialiser l’upload du workbook avec le call Initiate File Upload puis l’envoyer par portions. Une fois que les portions sont liées, on fait appel au call publish workbook. Ainsi la requête ne contient pas le workbook à publier dans le fichier.
Précisons au passage ce qu’est une boundary string. Il s’agit d’une ligne de caractères qui peut contenir du texte et des numéros random et qui sert de séparateur entre les différentes parties du formulaire soumis.
Point positif, il y a des REST Samples de disponibles dans la documentation de Tableau mais beaucoup sont en Python et Java, et nous, dans la SynalTeam, travaillons en Javascript.
Nous avons ensuite essayé plusieurs fois d’attacher des fichiers issus des workbooks faisant moins de 64 Mo, directement dans la requête : en faisant des buffer, des form data, en mettant le contenu brut…mais rien ne passait.
Certains collègues devs ont ensuite essayé d’utiliser des librairies extérieures pour parser les xml – recréer un fichier de requête propre, mais ça ne passait toujours pas.
Mais, après plusieurs jours de recherche, alors que nous nous apprêtions à passer en Python, un développeur de la SynalTeam est tombé sur ce lien : http://tableaulove.tumblr.com/post/108939449540/nodejs-multipart-posts-against-tableaus-rest.
Une solution semblait ENFIN pointer le bout de son nez !
Nous avons donc décidé de partir de ce code-là pour effectuer notre upload en multi-parts. Et c’est ainsi que nous sommes parvenus à une “méthode hybride”, qui nous permet, peu importe la taille du fichier, de publier le workbook et lui attacher une fonction qui permet de lire le contenu du fichier puis de le publier ensuite.
Cette méthode, nous vous la partageons aujourd’hui car nous nous disons que nous ne sommes peut-être pas les seuls à avoir rencontré ce genre de difficultés avec l’API Tableau.
Help yourself, comme disent les anglophones !
Explication de code, rien que pour vos yeux !
Code ligne 1 à 11 :
Pour faire fonctionner notre solution hybride maison de POST via l’API Tableau vous aurez besoin d’appeler les bibliothèques Axios, Fs, FormData et XML Writer. La fonction a besoin de 5 paramètres pour fonctionner qui sont des objets Js et ID particuliers.

Code ligne 13-30 :
A partir de là, on va charger le contenu du workbook que l’on veut publier et ça va se faire en deux étapes : chargement du contenu (1er appel à l’API de Tableau Server pour aspirer le contenu du workbook sur un site particulier – siteId) et sauvegarde du contenu du workbook dans un fichier sur le disque (l. 30).

ATTENTION : suite au fonctionnement propre à Tableau Server, le token n’est valable uniquement que pour un site donné. Si on upload le workbook sur un nouveau site toujours dans le même Server il faut changer de token.
NB : Évidemment si on change de Tableau server, il faut demander un nouveau token, mais il ne sera toujours valable que pour un site donné au sein du server.
Code ligne 32 à 80 : “c’est là que le fun commence” ! \o/
On commence tout d’abord à réécrire avec la bibliothèque XML Writer, la requête XML proprement au bon format pour éviter les erreurs. Ensuite, on va initialiser un objet FormData – ligne 52-53 pour créer deux couples de clés-valeurs (requête XML réécrite + contenu du workbook).
Maintenant on va pouvoir uploader ce nouvel objet sur un nouvel environnement.
On va soumettre l’objet FormData puis on construit la requête de soumission. (jusqu’à ligne 80+/-)
ATTENTION ! Ligne 65 : penser à mettre le nouveau token car on a, au minimum, changé de site.
Ligne 66 : déclarer quelle est la “boundary string” dans les headers de notre requête. Etape indispensable pour être sûr que les différentes parties soient identifiées correctement.
A noter aussi, nous nous servons du status code de la réponse de l’API Tableau. Tout ce qui est différent de 201 est une erreur.
La façon dont on exporte les data sources dans Tableau est quasiment identique. Il s’agit du même genre de problématique, les appels se ressemblent beaucoup et le traitement aussi. Sauf que là où on a besoin de l’objet Workbook ligne 10, ça devient un objet DataSource.

Et c’est donc grâce à ce petit bout de code que nous sommes venus à bout de cette impossibilité de faire fonctionner le POST avec l’API Rest Tableau !
Devant le peu d’informations que nous avons trouvé en ligne pour résoudre ce problème, nous nous sommes dit que partager notre méthode pourrait forcément aider quelqu’un·e un jour et si c’est le cas, n’hésitez pas à nous laisser un petit commentaire ! D’ailleurs, si vous avez aussi rencontré ce problème, nous serions ravis de savoir comment vous l’avez résolu !
En attendant, nous mettons à disposition notre petit bout de code magique !
Télécharger le fichier