mardi 22 juin 2010

5 clés pour intégrer des composants existants à une application SaaS

Depuis plusieurs années maintenant, des éditeurs et des prestataires se lancent dans le SaaS pour compléter leurs gammes de services et de logiciels traditionnels. Cependant, pour réduire les coûts de développements et les délais de mise de sur le marché, la tentation est grande de réutiliser des composants existants en les intégrant au sein d’une plate-forme SaaS. Il peut s’agir de composants purement techniques (téléchargements, conversions d’images ou de documents bureautiques), de services métier à forte valeur ajoutée comme la LAD (lecture automatique de documents) ou encore de requêtes vers de services tiers.

Un schéma simple et efficace est de connecter à l’application SaaS des composants métiers ou techniques qui remplissent une ou plusieurs fonctions précises. Chacun de ces composants communique directement avec l’application principale par des files de messages ou des services web.
Lors de la mise en œuvre, il faut être particulièrement vigilent, car le monde du SaaS a des exigences très spécifiques. Voici un petit tour d’horizon des contraintes à connaître et des pièges à éviter :

Haute disponibilité :
L’objectif de disponibilité des applications SaaS est le 100%. Lors de l’intégration d’un composant existant à une architecture SaaS, il faudra donc définir une stratégie prenant en compte la gestion des pannes de ce composant, de ses montées de versions. De même si ce composant repose lui-même sur un composant tiers (i.e. une base de données), il faudra prendre en compte les indisponibilités (planifiées ou non) de ce sous-composant.
Dans tous les cas, l’application principale ne devra jamais se retrouvée bloquée.

Scalabilité :
La scalabilité peut être définie comme la capacité d’un système à étendre (ou réduire) facilement ses ressources à mesure que la charge augmente (ou diminue). Si une application SaaS est bien conçue, sa capacité de traitement évolue linéairement avec la quantité de processeurs/RAM qui lui est allouée.
Malheureusement, certaines applications ne sont pas capables de tirer correctement partie d’une architecture multiprocesseur. Dans ce cas, il faudra déployer l’application sur plusieurs machines (éventuellement virtuelles) et mettre en place un mécanisme de répartition de charge (load-balancing). Cela peut engendrer des coûts d’exploitation supplémentaires, ainsi que des délais de mise à disposition importants de ces nouvelles machines selon l’hébergeur.

Temps de réponse :
Dans le monde du web, l’utilisateur déteste attendre… et il a raison ! Quelques secondes, ou au plus quelques dizaines de secondes si une barre de progression est là pour le distraire. La maîtrise des temps de réponse est donc primordiale, pour gagner de nouveaux clients, mais surtout pour satisfaire et conserver ses clients actuels.
S’il y a des doutes sur la capacité d’un composant à s’exécuter dans un délai prévisible et raisonnable, il vaut mieux prendre ses précautions : on pourra lancer le service de manière asynchrone pour rendre la main immédiatement à l’utilisateur, puis dans un second temps le notifier du succès de l’opération.
On peut aussi déclencher au lancement du service un compte à rebours : si ce dernier se termine avant l’arrivé des résultats attendus, on pourra lui présenter des résultats partiels et éventuellement lui proposer de poursuivre la recherche pour obtenir de nouveaux résultats.

Exploitation :
Une fois que la plate-forme de production est installée chez l’hébergeur, pas question de se connecter tous les matins pour prendre la température des applications. Nos petits composants sont lâchés dans la nature, comme des skippers au milieu de l’océan. Il est donc primordial qu’ils soient capables de communiquer eux-mêmes en indiquant périodiquement leur état, en indiquant leurs défaillances dès qu’elles surviennent, ainsi qu’en prenant des mesures pertinentes dans leur environnement : espace disque, accès aux ressources externes, consommation de licences, etc. Les modes de communication peuvent être variés, voire même combinés : emails, alertes vers un outil de supervision de plates-formes (Patrol, $Universe), portail de supervision métier accessible en client léger, etc.

Documentation :
D’une manière générale, on documente pour éviter que les seules personnes capables de faire fonctionner un logiciel soient ceux qui l’ont développé ! Ceci prend tout son sens dans le monde du SaaS où il est fréquent que les équipes d’exploitation soient localisées dans des pays émergents et avec lesquelles la communication se fait obligatoirement en anglais. L’anglais entre non anglophones… quel bonheur !
Il est également important de garder à l’esprit que les exploitants n’ont aucune idée de ce que fait notre application. Les documents d’installation devront donc être le plus clair possible, et prévoir des procédures de vérification permettant à minima de s’assurer que l’application est bien opérationnelle à la fin de l’installation !


vendredi 4 juin 2010

Bien nommer les classes et les méthodes d’une API

Pour les classes, cela DOIT être facile...

Nommer une classe est normalement simple : il suffit de choisir un terme suffisamment général et décrivant le mieux la notion gérée par cette classe. Si la classe est bien conçue, et qu’elle respecte le principe de responsabilité unique, la nommer ne devrait pas présenter de difficultés.
Si lui trouver un petit nom s’avère difficile, ou qu’aucun nom ne paraît raisonnablement satisfaisant, il est probable que cette classe fasse trop de choses. Il n’y a alors qu’une seule chose à faire : la tronçonner ! Une autre astuce est de s’imposer de commenter la classe en une seule phrase. Si cette phrase est impossible à écrire, ou si elle n’a rien à voir avec le nom choisi, il faut changer le nom, ou bien découper la classe.

... c’est pour les méthodes que ça se complique !

Nommer correctement les méthodes publiques d’une classe a son importance. Récemment, j’ai dû enrichir les API d’un de nos logiciels. Celles-ci sont destinées à des développeurs tiers qui éventuellement ne font pas partie de notre société. Pas question donc de laisser des ambigüités ou des incohérences. Et lorsque on est en présence d’un package contenant des dizaines de classes, et que chacune d’entre elles comprend une ou plusieurs dizaines de méthodes, on se retrouve donc à fournir plusieurs centaines de méthodes, et quelques règles s’imposent :

Utiliser l’anglais : ne connaissant pas à priori quelle sera la nationalité des développeurs qui utiliseront l’API, il faut s’imposer la langue internationale de l’informatique : l’anglais.

Débuter les noms par un verbe indiquant aussi précisément que possible le type d’action réalisée :
    countUsers() : compte le nombre d’utilisateurs
    isExpired() : indique si le compte-utilisateur est expiré

Combiner des mots entiers jusqu’à décrire l’action réalisée par la méthode. 
    getExpirationDate() : retourne la date d’expiration
    notifyAllClients() : notifie tous les clients

Eviter les informations inutiles : éviter de faire porter au nom de la méthode une information non indispensable, ou bien disponible ailleurs.
Ex : si une méthode renvoie tous les employés d’un service, et qu’elle s’applique soit sur un objet Service, soit qu’elle prend un objet Service en paramètre, il est inutile de l’appeler getEmployeesByService ; getEmployees est suffisant.

Ne pas pas utiliser le mot « And » : si le recours au mot « And » est requis, c’est que la méthode à nommer réalise plusieurs actions. Dans ce cas, il faut la tronçonner. En effet, le principe de responsabilité unique s’applique à tous les niveaux, y compris au niveau d’une méthode.

Conserver la même logique dans toute l’API : ce qui est important, ce n’est pas de se faire des nœuds au cerveau pour savoir si une méthode qui met à jour un objet métier doit commencer par update ou modify. En revanche, ce qui est important, c’est de faire un choix, et de l'appliquer à travers toute l'API.

Bien-sûr, ces quelques règles ne font pas le travail à la place des développeurs, et elles peuvent être complétées. Mais les respecter m’a permis de produire une API cohérente ce qui au final facilite le travail des utilisateurs.