Nota : ce billet n'a rien d'original puisqu'il se contente de reprendre quelques idées développées par Jeff Lindsay, évangéliste des Web Hooks, sur son blog, dont je vous recommande évidemment la lecture.

Les hooks sont une technique de programmation classique par laquelle un logiciel définit une interface permettant à des composants externes d'étendre ou modifier son comportement. Par exemple, avant et après chaque action, le logiciel regarde si des modules complémentaires ont souhaité être avertis, et si oui il les appelle. Un des exemples les plus connus d'utilisation de hooks est sans doute les logiciels de gestion de source, comme Subversion, qui permettent de définir des actions à exécuter avant ou après chaque commande. Des logiciels comme Drupal, Dotclear, Wordpress... utilisent également ce mécanisme comme base de leur système d'extension. Dans Firefox, les Overlay sont des hooks.

On pourrait sans doute traduire hook par dérivation, comme dans un circuit électrique. Une application utilisant des hooks est dérivable, on peut facilement en modifier le flux standard pour le faire passer par d'autres chemins.

Je pense que c'est une condition de plus de la liberté d'une application: pour être réellement libre, un programme devrait être facilement extensible, dérivable, fournir des points où accrocher des modules additionnels sans devoir toucher à l'application elle-même. Si pour adapter un programme à ses besoins, on est obligé d'intervenir dans son code source, cela oblige à maintenir sa propre version du source, à recompiler l'ensemble à chaque nouvelle révision, etc. Ceux qui ont connu phpBB avant la version 3 se souviennent du cauchemar pour installer un module complémentaire : il fallait appliquer des modifications directement sur le code source, et on n'en finissait plus de devoir lutter avec les problèmes de compatibilité entre modules ou à chaque nouvelle version mineure du logiciel. Les hooks, en facilitant l'extensibilité du code, le rendent plus ouvert.

Cette solution n'est bien sûr pas parfaite. Parmi les problèmes qu'elle pose, j'en relève deux pour mieux appuyer la suite de mon billet:

  • sauf rare exception, les extensions doivent être écrites dans le même langage que l'application, ce qui implique que vous soyez relativement à l'aise avec ce langage. Certes des ponts existent entre différents langages[1], mais ce sont souvent des solutions lourdes à mettre en œuvre;
  • elles nécessitent d'installer le module complémentaire, donc du code, sur le même serveur que l'application. Ce qui est rarement possible si vous utilisez une application hébergée. Par exemple, ce blog est hébergé par la plate-forme de Gandi, ce qui a quelques avantages mais m'empêche d'installer les extensions que je veux;

Une solution à ces deux point commence à poindre son nez : utiliser des Web Hooks pour étendre une application en ligne. Les Web Hooks ne sont rien d'autre que des pages web qui exécutent une action et peuvent éventuellement renvoyer un résultat. On peut les voir comme un sous ensemble des services web REST: on déclenche une action en appelant une URL via une requête GET ou POST, et on peut récupérer le résultat, ou pas.

Les Web Hooks sont une réponse relativement élégante à l'extensibilité des applications hébergées. Il suffit de permettre à l'utilisateur de spécifier des URL à appeler pour chaque hook défini dans l'application, en précisant si celle-ci doit attendre ou non un résultat. Dans le premier cas, le coût est élevé en terme de performances, car il faut compter avec la latence du réseau, gérer les indisponibilités, etc. Mais dans le second, le coût est faible, on se contente d'envoyer une requête sans se soucier du résultat. Les applications sont nombreuses, du simple ping d'un Hub pour annoncer la publication d'un contenu, à des interactions plus complexes entre applications, par exemple pour gérer les droits d'utilisateurs. Même si aucune API n'existe entre deux applications, on pourra aisément les faire communiquer via des hooks, avec un minimum d'intervention au niveau des serveurs qui les hébergent.

Les Web Hooks permettent également d'augmenter la réutilisabilité du code, à la manière de bibliothèques externes. Imaginons par exemple un service qui prenne en entrée un document au format Atom et le publie via le mécanisme PubSub de XMPP. Cet hook pourrait lui-même être appelé par des hooks déclenchés depuis Dotclear, WorPress, Status.Net et qui convertiraient juste les données en Atom. On peut ainsi mettre en place une architecture inspirée des commandes Unix, avec des hooks se contentant de tâches élémentaires et reliés les uns aux autres via des tuyaux.

Si vous voulez tester cette solution, un plugin pour WordPress, HookPress, permet déjà d'appeler des URL en réponse à certains évènements. tcWebHooks en fait de même pour TeamCity, un serveur d'intégration continue. Cette présentation montre l'utilisation de Web Hooks avec PBWiki et Yahoo Pipes. De plus en plus de service permettent d'utiliser cette technique : Google Code, github, Shopify (une boutique en ligne)...

En utilisant des Web Hooks, on peut ainsi étendre une application sans la modifier, et en utilisant le langage de son choix. Les hooks favorisent également les logiques de flux et facilitent les communications entre services.

Pour ce qui est de l'hébergement du hook, la meilleure solution est bien sûr de disposer d'un bout de serveur où installer ses scripts. Mais ce n'est pas une condition indispensable, car des solution en ligne existent et vont probablement se multiplier. Google AppEngine vous propose d'héberger des applications Python ou Java[2] directement sur les serveurs de Google. L'hébergement propose de plus des bibliothèques offrant des fonctions spécifiques au contexte. Feu AppJet, qui a hélas fermé le 1er juillet 2009, proposait lui d'héberger des applications écrites en JavaScript (je reviendrai très bientôt sur le retour de JavaScript sur le serveur). Techniquement, il utilisait je crois le moteur JavaScript Rhino, développé en Java par Mozilla, en le faisant tourner au dessus d'AppEngine. AppJet offrait de plus un IDE en ligne et des bibliothèques spécifiques. En se basant sur la même architecture, et suite à la fermeture d'Appjet, Jeff Lindsay a lancé Scriptlets, dont le code source est disponible. Il se base lui aussi sur AppEngine et supporte pour l'instant JavaScript, PHP et Python. J'ai également découvert le service hookhup qui héberge des scripts JavaScript. Si vous en connaissez d'autres, n'hésitez pas à les signaler dans les commentaires.

Avec Bespin, qui permettra bientôt de disposer d'un véritable environnement de développement complet en ligne, on dispose de pratiquement toutes les briques pour que les Web Hooks prennent leur envol. Et j'espère que ça sera le cas. Car je vois à ce type de plateforme un intérêt majeur : permettre de bidouiller très facilement le Web côté serveur. Il suffit d'écrire un script dans son langage de prédilection, de le déposer sur un serveur, et d'enregistrer l'URI du hook dans l'application que l'on veut modifier. De même que de nouveaux outils rendent chaque jour plus simple la bidouille en JavaScript dans le navigateur, le Web Hook permettent d'expérimenter sur le serveur. Avec un minimum de connaissances, aidé par un IDE en ligne, on va pouvoir commencer à écrire des petits bouts de code pour modifier et étendre les applications en ligne que l'on utilise. C'est un pas de plus dans la ré-appropriation du Web. Et c'est à ce titre que les Web Hook sont pour moi une des briques de l'Open Web. Pour participer, ll ne vous reste plus qu'à rendre vos applications Web dérivables...

Notes

[1] par exemple jsbridge entre JavaScript et Python, ou PHP/Java Bridge

[2] et par extension dans les langages pour lesquels il existe un interpréteur en Java, comme Ruby via JRuby, JavaScript avec Rhino, etc