13 Fév 2017

Comment transformer facilement de la donnée avec lodash ?

Comme nous l’avons vu dans d’autres articles, Lodash est une librairie très riche et puissante qui nous facilite la vie. Elle permet par exemple de construire très rapidement d’autres petites libraires tout simplement. Dans cet article, nous allons implémenter ensemble un petit composant qui permet de transformer des données d’un format vers en autre (avec quelques autres features) en quelques lignes. Nous utiliserons en autres l’innocente mais tellement puissante fonction _.get de cette librairie.

 

 

lodash

 

 

I. Précisons le problème

En effet, il arrive que dans nos projets nous récupérons de la donnée (depuis une bdd, ou une API) sous un format qui ne nous convient pas :

  • Les données récupérées sont trop volumineuses,
  • Les données récupérées sont mal formatées,
  • Les données récupérées ne sont pas structurées comme nous le souhaitons,
  • Les données récupérées nécessitent de petits traitements unitaires sur certains champs,
  • etc.

 

Comme annoncé plus haut, ce que je vous propose à travers cet article c’est de créer une première version d’un utilitaire permettant de répondre à cette problématique simplement.

 

Admettons que nous recevons le bloc de données suivants :

et que nous devons le transformer en :

 

Quelles transformations sont à faire pour en arriver au format cible ?

  • La valeur contenue identity.id sera copiée dans un attribut id d’un nouvel objet,
  • La valeur contenue identity.firstname sera copiée dans un attribut firstname de ce même nouvel objet,
  • La valeur contenue identity.lastname sera copiée dans un attribut lastname de ce même nouvel objet,
  • Tous les champs (ou presque) de identity.address sont concaténés et placés dans un attribut oneLineAddress de ce même nouvel objet,
  • Seul le dernier job (identity.jobs[x].type.subfield === LATEST) est récupéré et la valeur de son name est placée dans un attribut job de ce même nouvel objet.

 

Alors bien sur, nous pourrions prendre “manuellement” chaque valeur et construire l’objet valeur par valeur mais ce que nous proposons est d’avoir une fonction qui à partir d’un template va transformer les données sources sous le format cible. Cela permettra de réutiliser rapidement et à chaque appel d’API ou de BDD notre librairie.

 

II. Construisons la solution

Mais à quoi ressemblerait le fameux template ? (phase de conception)

L’idée serait d’avoir un template ayant la structure attendue et de lui mettre en valeur le path dans l’objet source.

Pour les trois premiers champs, cela donnerait ceci :

Mais comment procédons-nous pour la l’adresse en une unique ligne et pour le nom du dernier job connu ?

Il nous faudrait la possibilité de passer à notre librairie des fonctions qui réalisent les petits traitements dont nous avons besoin :

En effet, pour le champ oneLineAddress, il nous faut concaténer une partie des champs ci-dessous :

Première étape, on va réutiliser la même technique avec les champs à concaténer dans notre template :

Ensuite on se créé un espace où indiquer dans notre template quelles opérations concernant ce champ nous devons réaliser:

Et on reproduit la même chose pour le champ job :

Et voilà nous avons un joli template prêt à l’emploi !

III. Implémentons la solution

Première étape, écrivons notre/nos tests et posons la signature de notre méthode :

… puis définissons l’objet de retour :

 

Puis, Nous allons donc itérer sur chaque propriété du template pour lui associer le traitement idoine :

… on se rend compte que ce bout de code peut déjà être remplacé par un reduce :

 

Troisièmement, dans le cas “simple” allons chercher la donnée à “copier/coller” avec la méthode _.get de lodash qui va aller chercher dans l’objet json source la bonne donnée (avec le chemin vers cette dernière mis à plat et séparer par des ‘.’) :

La fonction _.get prend trois paramètres :

  • le premier qui correspond à l’objet source,
  • le second qui décrit le chemin vers l’attribut voulu (chemin dans l’arborescence de l’objet source),
  • et le troisième qui correspond à une valeur par défaut.

Exemple :

 

 

Et sinon dans le cas des objets complexes, il faut alors faire le même traitement de manière récursive (j’ai donc créé une sous méthode pour se faire) :

… il ne nous reste plus que le cas des champs nécessitants des opérations spécifiques :

Comme vous pouvez le voir, on se sert de la méthode _.find de lodash qui va nous permettre de retrouver s’il y a une opération spécifique à exécuter et si oui laquelle.

Intégrons ces petites instructions à notre fonction :

 

Et vous voilà avec une librairie légère de mapping de données vous backend javascript. Bon usage.

Pour informations, j’ai regroupé sur ce repository git les sources qui ont servi à écrire cet article : node-data-transformer.

A bientôt

 

FacebookTwitterGoogle+LinkedInViadeoShare