Introduction à la librairie ZIO en Scala

ZIO est une librairie qui fait beaucoup de bruit dans la communauté des développeurs Scala depuis quelque temps. 

Comme indiqué sur son site officiel, ZIO est une librairie dédiée à la programmation asynchrone et concurrente, basée sur le paradigme de la programmation fonctionnelle “pure”. 

Dans le détail, que propose cette librairie ? 

Pour commencer, nous pouvons revenir un concept clé de la programmation fonctionnelle dite pure, la transparence référentielle. Selon Wikipedia, nous pouvons définir ce concept comme ceci : 

“La transparence référentielle est une propriété des expressions d’un langage de programmation qui fait qu’une expression peut être remplacée par sa valeur sans changer le comportement du programme.” 

referential transparency

Source : impurepics.com 

On peut aussi dire qu’une fonction est pure si :

  1. Elle est déterministe (elle renvoie toujours le même résultat pour les mêmes paramètres d’entrée) 
  1. Elle est totale (elle renvoie toujours un résultat) 
  1. Elle ne produit pas d’effet de bords, c’est à dire de modifications d’état externe à la fonction elle même 

Ces propriétés sont très intéressantes car elles permettent de rendre le code plus prédictible et le raisonnement autour de son comportement plus simple. Et tout cela nous aide à réduire le nombre de bugs rencontrés en production, tout en permettant de refactorer notre code avec plus de tranquillité!

Pour nous aider à écrire des expression respectant la transparence référentielle et des fonctions pures, ZIO utilise une technique bien connue dans la programmation fonctionnelle, qui est d’encapsuler tous les “effets”, c’est à dire les interactions avec le monde extérieur (lecture de fichier, écriture dans une base de données) et tout ce qui n’est pas déterministe (accès à l’horloge du système). Ces effets sont encapsulés dans une structure (appelée monade) qui fonctionne de manière lazy (paresseuse) : les effets sont d’abord décrits mais ne sont exécutés que plus tard. Ils sont traités comme des valeurs, peuvent donc être combinés, optimisés, et ensuite exécutés quand tous l’arbre des effets est défini.  

Dans cet exemple, on peut voir que ZIO est bien adapté pour écrire un limiteur de débit, et qu’il serait plus difficile de faire la même chose avec un système qui exécuterait immédiatement les effets décrits dans le code. 

Un autre point important est la gestion d’erreurs. Avec ZIO, un effet peut retourner une valeur de type A ou une erreur de type E. Par exemple une valeur de type IO[String, Int] représente un effet qui peut échouer en renvoyant un message d’erreur de type String ou résultat de type Int (entier).  Ceci permet de répondre au point 2 des règles d’une fonction pure. Une fonction renvoyant un résultat de type IO[String, Int] renverra toujours ce type de résultat, que l’on rencontre une erreur ou non. Ce ne serait pas le cas si la fonction lançait une exception en cas d’erreur. 

ZIO propose aussi d’autre fonctionnalités et avantages :  

  • Un système de threads légers appelés Fibers permettant de consommer moins de threads système 
  • Une librairie de streaming (zio-streams) comparable à Akka Streams 
  • L’abstraction Ref qui permet de manipuler des références muables en assurant l’atomicité des opérations et le côté “thread safe” 
  • Queue, qui est une queue de données asynchrone 
  • ZLayer, un système de gestion et d’injection de dépendances intégré à la notion d’IO
    • et donc la gestion des environnements de test ou de production avec lesquelles les IO intéragissent
  • STM (Software Transactional Memory), un système d’effets transactionnels  
  • ZIO test, un outil de test (vous l’aviez deviné)
  • Et beaucoup d’autres choses 

La communauté a également connu une croissance importante ces derniers mois et un grand nombre de projets basés sur ZIO sont nés, par exemple ZIO Kafka, ou ZIO Keeper (qui permet d’interagir avec le service Zookeeper).  

Si vous souhaitez en savoir plus sur ZIO, n’oubliez pas que Kaizen Solutions propose plusieurs formations Scala!  

Vous pouvez également utiliser le template fourni par Kaizen pour démarrer un projet de type Web Service avec Akka HTTP et ZIO. Ce projet utilise ZLayer pour l’injection de dépendances et la glue entre Akka HTTP et ZIO est inclue.