Aujourd'hui, je vais essayer de parler un peu d'AppEngine.
Rapidement
Commençons par un peu de présentation. Pour ceux du fond qui ne le savent
pas, AppEngine, c'est le système d'hébergement mutualisé made in google pour
des applications développées soit en Python, soit en Java. L'idée est donc de
développer tranquillement son application, et de laisser à google la
responsabilité de l'infrastructure et de la montée en charge. Niveau
facturation, on ne paie que ce qu'on consomme à partir d'un certain quota.
Déjà, le premier point que j'aimerais souligner, c'est que nous disposons
enfin d'une offre solide et abordable d'hébergement mutualisé pour Java (pour
python, on pouvait déjà trouver son bonheur en fouillant un peu). Ça n'a l'air
de rien comme ça, mais j'ai envie de dire c'est pas trop tôt. Voilà près de 10
ans qu'il est très facile de trouver un hébergement mutualisé pour Php, mais
qu'il est très difficile voir impossible de trouver une offre équivalente pour
d'autres technologies. Du coup, PHP est presque devenu un standard sur le net,
alors qu'il est sans doute difficile de trouver pire environnement de dev
(support des TU lacunaire, pas de refactoring, un style très procédural, une
communauté globalement très mal formée et sensibilisée aux bonnes pratiques de
développement, pas de framework unifié de base, etc. etc.). Alors bien sûr, je
ne pense pas qu'AppEngine va réussir à inverser la tendance, mais j'espère
juste qu'à l'avenir, des offres d'hébergement pour des technologies/langages
plus "agréables" comme Python ou Ruby vont fleurir sur le net. Bref, après un
paragraphe qui je suis sûr, va me faire lapider par tous les aficionados de
php, passons aux choses sérieuses (vous pouvez m'envoyer vos cailloux par
email).
Un peu (beaucoup) de technique
Parlons un peu technique. Je vais me contenter de parler de la partie java
d'AppEngine, car je ne suis pas du tout un expert python, et je n'utilise que
des langages pour lequel il existe un IDE avec un bon support du refactoring
(et ceux qui disent que ces outils ne servent juste qu'à palier les manques
d'un langage n'ont juste rien compris à ce qu'est fondamentalement le
refactoring).
En terme de développement et de déploiement, si vous utilisez le plugin
eclipse de google, tout est excessivement simple, et mérite à peine d'en
parler : vous codez, vous testez, et vous déployez en un seul clique. Un
serveur de développement AppEngine est fourni pour vous permettre de faire des
tests d'intégration, et TDD peut s'utiliser sans aucune contrainte, en fakant
rapidement l'accès aux données. IntelliJ IDea dans sa version complète je crois
fournit également un support pour tout ça. Là où ça commence à être compliqué,
c'est si vous voulez utiliser maven pour automatiser votre build et votre
intégration. Clairement, ce n'est pas au point, et j'ai laissé tomber l'idée
pour le moment.
Ceci étant dit, abordons les limitaions d'AppEngines. Pour garantir la
scalabilité et la mutualisation de votre application, Google a dû imposer des
contraintes de taille.
Première contrainte, toutes les fonctionnalités de l'API java ne sont pas à
votre disposition. Les deux restrictions qui sautent aux yeux mais qui sont
assez logiques sont l'impossibilité bien sûr d'écrire sur le FileSystem, ainsi
que l'interdiction de créer des threads. Il y en a d'autres, mais je vous
laisse la surprise, je ne veux pas trop spoiler.
Deuxième contrainte très importante, et c'est celle qui va le plus nous
intéresser : le stockage de vos données. Et oui, vous ne pouvez pas
utiliser votre cher SGBD. C'est assez logique en fait. Pour garantir la
scalabilité et la vitesse d'accès à vos données, google fournit son propre
système, BigTable, pas du tout relationnel. Bon si cette base n'est pas
relationnelle, qu'est-elle donc? Elle est hiérarchique. Ce genre d'approche
permet de répartir bien mieux vos données sur N cluster, là ou les SGBD eux ont
beaucoup plus de mal. Ce miracle est dû au fait que ces approches ne se
concentrent par sur la cohérence des données, mai sur leur accessibilité et
leur distribution, là où un sgbd se concentre sur l'accessibilité et la
cohérence. Le bémol est donc que vous n'avez pas la garantie qu'à un instant T,
une entité donnée est cohérente sur l'ensemble des noeuds. Ok, une base
hiérarchique, c'est quoi donc? Vos données sont organisées en entités,
contenant des propriétés clef/valeur de types supportés. Ces valeurs peuvent
être d'autres entités. Le DataStore regroupe les entités par groupe, chaque
groupe ayant une racine. Et là, normalement, si comme moi vous aimez Domain
Driven Design, ça doit faire tilt dans votre tête. Entités? Groupe? Racine?
Pouvons-nous réécrire ça en Agrégat, racine d'Agrégat et entité? Et bien oui,
nous le pouvons. Nous avons face à nous un système de stockage mimant les
grands concepts de DDD, et ça, c'est la classe. Nous pourrions normalement
sauter de joie, mais hélas non, pas encore. Pour nous permettre de décrire la
persistence, Google nous fournit une implémentation partielle de JDO ou JPA.
Voilà déjà un premier point noir à mes yeux : pas d'ignorance de la
persistance pour nos objets du domaine, vu que le mapping se fait donc
nécessairement par annotations. Deuxième gros point noir, pour modélier une
relation entre deux racines d'agrégats, nous devons nécessairement passer par
la clef. Et oui, pas de mapping transparent entre deux racines : l'un ou
l'autre contient la clef qui va nous permettre de faire la requête adaptée.
Dernière contrainte que je vais aborder : le développement itératif. Si
vous suivez un modèle de développement agile correctement implémenté (ok disons
que vous utilisez XP, ça ira plus vite), vous êtes incrémental et itératif.
Itératif veut donc dire que votre modèle évolue au fur et à mesure des besoins
et de votre compréhension. Si le modèle évolue, nécessairement sa persistance
aussi. Le DataStore n'a pas du tout besoin que toutes les entités d'un même
type possèdent les mêmes propriétés, donc on pourrait croire qu'en théorie pas
de soucis. Oui mais si vous devez tout de même faire une mise à jour des
vielles entités pour une raison X ou Y (notamment si vous avez ajouté un type
valeur comme un boolean), comment faire? Voilà tout le soucis, actuellement,
même si Google planche sur le sujet, vous ne pouvez pas facilement. Vous avez
une limite de 1000 entités par requête, et une requête a un temps de vie très
court accordé par le système avant d'être tuée. Il existe bien sûr des
solutions de contournement, mais rien de bien simple et de pleinement
satisfaisant.
Et pour conclure
Bien voici venu le temps d'une grosse conclusion. Ce que j'aime, voir ce que
j'adore chez AppEngine, c'est enfin l'accès à un hébergement abordable et de
qualité pour Java. Vous pouvez utilisez si vous développez avec AppEngine en
tête dès le début vos frameworks et techos préférés (Groovy, Restlet, Spring,
Guice <ajoutez ici votre techo>). J'adore également, et ce n'est pas
seulement dû à AppEngine, l'attaque qui est faite aux SGBD traditionnelles. Des
technologies solides de remplacement voient enfin le jour grâce à ces nouveaux
services, et on peut espérer voir la fin de notre vivant des ces applications
codées en procédures stockées, soit disant pour être performantes. Là vous
n'avez pas le choix : votre métier est dans votre application, pas dans la
base. Bien sûr, ce n'est pas encore complètement au point à mes yeux tant que
l'ignorance de la persistance n'est pas atteinte, mais c'est sur une très bonne
voie. Si vous ne voulez pas dépendre, à juste titre, de sociétés comme Google
et Amazon pour stocker vos données, des implémentations solides et open source
de ces nouvelles bases de données sont disponibles.
Enfin, je m'excuse si ma vulgarisation des théories derrière BigTable est
vraiment lapidaire, mais je vous laisse bien entendu l'opportunité de me
fustiger dans les commentaires 