Unhosted

Aventures Unhosted

Une traduction approximative du Journal de bord officiel du No Cookie Crew

d’après Unhosted Adventures
by Michiel B. de Jong

10. Relié des choses ensemble sur le world wide web

Le web comme base de données

Si, comme moi, vous arrivez dans le développement d'applications web unhosted par la porte de la conception logiciel, alors vous allez devoir apprendre quelques trucs pour faciliter cette transition. Pour commencer, évidemment, JavaScript et le Modèle Objet de Document (DOM) (“Document Object Model”) que nous manipulons grâce à lui, ressemble beaucoup plus à de la programmation asynchrone événementielle qu'à de la programmation procédurale ou orientée objet.

L'organisation des variables par “closures” plutôt que par “classes” demande une certaine habitude. Récemment, il y a une évolution qui promet de rendre cela un peu plus intuitif, mais comme toujours lorsque vous changez de plates-forme de programmation, il est possible d'en apprendre la syntaxe en une journée, mais en saisir l'état d'esprit peut vous prendre une année.

Ce n'est cependant pas le seul changement de paradigme que vous allez devoir faire. Le Web, rappelez-vous, a été conçu à l'origine comme une collection de documents reliés entre eux par des liens hypertextes. Ces liens en sont sa structure atomique fondamentale. Cela implique deux grandes différences par rapport à la conception traditionnelle de logiciel.

Premièrement, chaque enregistrement de données, ou en termes web, chaque document, fait référence à d'autres documents en utilisant des indications évoluant dans l'ensemble des espaces de noms préfixés des adresses URL, et cela peut ou, peut ne pas fonctionner.

Deuxièmement, ces données ne sont pas chiffrables. Il est possible de chiffrer les données accessibles en suivant les liens d'un document spécifique, mais il ne sera jamais possible de récupérer une liste exhaustive de tous les contenus du Web.

Bien sûr, ces deux caractéristiques peuvent être surmontées en limitant les données que votre application va utiliser à un seul domaine DNS spécifique. Mais dans sa conception, le Web est ouvert, et cela en fait une sorte de base de données plutôt amusante.

Contenu intégré

Supposons que vous développiez une application pour un journal, application qui permettra aux gens de lire les numéros de ce journal sur une tablette, et ce, comme on dit, de manière “enrichie”, donc avec un design “responsive”, une mise-en-page plein écran, une utilisation interactive des “gestures”, etc. Vous organiseriez probablement tout ça en deux parties avec d'un côté, une interface système (“shell”), pour tout ce qui concerne les parties fixes de l'application, et de l'autre côté, les données (“content”), pour tout ce qui concerne le contenu réel du numéro du jour du journal, comme le texte, les images, etc.

Si vous deviez développer une telle application en utilisant une technologie non-web, les données du journal seraient enfermées dans l'application, dans le sens où l'utilisateur n'aurait évidemment aucune possibilité de partager un article spécifique du journal avec un ami. Par contre si vous développez cette application comme une application Web, alors la création de liens vers le contenu devient tout à coup très facile.

L'utilisateur devrait être en mesure de quitter le mode plein écran à tout moment, et verrait une URL dans la barre d'adresse lui permettant d'identifier le contenu actuel de l'écran. Dans une application web hébergée, cette URL peut être relative à l'utilisateur actuellement connecté, tel que défini par le cookie.

Dans une application web unhosted, il n'y a pas de cookie, et pas d'utilisateur connecté. Par contre, il peut y avoir un état relatif au compte remoteStorage connecté au lancement de l'application.

L'URL dans la barre d'adresse va changer chaque fois qu'un utilisateur va cliquer sur un lien, mais vous aurez souvent le besoin de concevoir votre application de manière à ce que le contenu soit récupéré de manière asynchrone plutôt que de charger une nouvelle page à chaque clic. Ce type d'architecture d'application est souvent appelé application à page unique (“one-page app, ou OPA”). Dans ce cas, vous aurez besoin d'utiliser history.pushState() pour mettre à jour l'adresse URL de manière à refléter l'état en cours de l'application.

En dehors de l'utilisation d'URL pour représenter l'état de l'application, d'une manière permettant aux utilisateurs de créer des liens profonds sur les états spécifiques (pages) de votre application, vous devriez également penser aux adresses URL des données que votre application récupère en arrière-plan.

Cela nous amène au point primordial suivant, le web de données.

Le Web des données

Comme nous l'avons dit plus tôt, le Web a commencé comme une collection de documents hypertextes, et de là a évolué vers cette plateforme d'application “html5” que nous connaissons aujourd'hui. Mais très tôt déjà, la possibilité de rendre les données du web lisibles non seulement pour l'homme, mais également pour des machines a été découverte.

Supposons que vous publiez une application web unhosted contenant une carte du monde. Cela signifie probablement que vous allez diviser votre application avec d'un côté une interface système (“shell”) capable d'afficher des parties d'une carte, et de l'autre côté les données topographiques.

Maintenant, grâce à la conception ouverte d'Internet il y a deux choses que vous pouvez faire, qui, sur d'autres plateformes d'applications, ne sont pas si simplement réalisables. En premier lieu, vous allez pouvoir permettre à d'autres applications de réutiliser les données topographiques faisant partie intégrante de votre application. Aussi longtemps que celles-ci seront dans un format de données reconnu, et si vous communiquez à d'autres développeurs d'apps les adresses URL sur lesquelles vous hébergez les données que votre application récupère de manière asynchrone, ils seront en mesure de les réutiliser dans leurs applications.

Et de même, vous serez en mesure de réutiliser des données provenant d'autres éditeurs dans votre application, et ce de manière transparente, pour autant que ces autres éditeurs utilisent un format de données lisible par l'interface système (“shell”) de votre application, et que vous ayez confiance dans ce qu'ils publient.

Il n'existe aucun moyen pour l'utilisateur d'extraire facilement les URLs des données que votre application va chercher en arrière plan. Les développeurs d'autres applications devront soit étudier votre application pour faire de l'ingénierie inverse, ou lire la documentation de l'API de votre application. Afin de faciliter ce travail, il est de bonne pratique d'inclure les liens de votre documentation au sein de vos données. De nombreux et bons formats de données permettent de prendre en compte cette exigence. Pour nos modules RemoteStorage, par exemple, nous utilisons des formats de données, qui pour la plupart, contiennent un champ “@context” avec une URL pointant vers une documentation. Les autres développeurs peuvent, lorsqu'ils consultent vos données, trouver ces liens, et cela augmente leurs chance de pouvoir déchiffrer le sens de vos données.

Le fait d'inclure les adresses URL de la documentation directement au sein de vos données apporte un deuxième avantage : Cela permet de rendre votre format de données particulièrement reconnaissable. Une adresse URL est un Localisateur de Ressource Universel (“Universal Resource Locator”), mais en même temps il peut tenir le rôle d'une “URI” : un Identificateur de Ressources Uniforme (“Uniform Resource Identifier”) permettant d'identifier de manière unique une ressource aussi bien que si on le pointait vers un document descriptif. Les chances pour que l'adresse URL relative à la documentation de votre format unique de données apparaissent dans un fichier par accident sont proches de zéro, par contre si un fichier contient votre URI, alors celui-ci donnera au lecteur l'indication que le-dit fichier se prétend être effectivement conforme à votre format de données, comme si cette chaîne de caractères jouait un rôle de carte d'identité.

Dans la pratique, cela ne fonctionne pas encore très bien, car il existe beaucoup de formats de données identiques, chacun avec leurs propres URI, qui se chevauchent et qui pourraient être fusionnées. Par exemple, Facebook publie, à propos des utilisateurs, des données lisibles par les machines avec l' adresse URI “http://graph.facebook.com/schema/user”. Cet URI est spécifique à Facebook, cela n'est donc pas d'une très grande aide pour la généralisation de ce format de données. Évidemment, ces données communiquées par Facebook lui sont en grande partie spécifiques, et il n'existe visiblement pas de bon moyen pour faire correspondre un “Facebook Like” et un “Twitter Retweet”, cela apparaît pour le moins partiellement inévitable.

L'intelligence émergente est un mythe

Un certain nombre de chose faites par les ordinateurs ont l'air magique. Si vous n'êtes pas programmeur (et même si vous l'êtes), il est souvent difficile de prédire ce que les ordinateurs vont être capables de faire, ou ne pas faire. Pour être plus précis, il semble qu'une croyance persiste parmi le grand public sur le fait que les données exploitables par une machine permettent aux machines de “comprendre” ces données, dans le sens où la machine serait en mesure de s'adapter aux fluctuations des formats de données, et ce tant que ces fluctuations restent documentées de manière à être toujours exploitable par une machine. Je suis désolé si cela est une découverte pour vous, mais cela n'est tout simplement pas vrai.

Tout cela dépend bien sûr de la façon dont vous définissez “compréhension”, mais en général, la règle de base est que chaque application est munie d'une liste finie de formats de données qu'elle prend en charge. Si un format de données n'est pas dans cette liste, alors l'application ne sera pas en mesure de faire un usage judicieux des données dans ce format, du moins sur le plan des fonctionnalités de l'application. Le développeur d'application doit mettre en place une prise en charge pour chaque format de données dans chacune de ces application, une-à-une, écrire des tests unitaires qui décrivent chaque réponse significative du comportement de ces données, et si ces tests sont réussis, alors l'application sera en mesure de prendre en charge le nouveau format de données.

Dés qu'un format de données est pris en charge, l'application peut le lire sans aucune supervision du programmeur (c'est ce que l'on entend par exploitable par une machine), et en utilisant les URIs, ou d'autres marqueurs uniques, elle peut même détecter à la volée, et avec un degré de certitude raisonnable, si le document qu'on lui adresse était destiné à être dans un certain format de données.

Mais une application ne peut pas apprendre comment réagir face à de nouveaux formats de données. Du moins pas dans l'état actuel des avancées de l'ingénierie des intelligences artificielles.

La seule exception à cette règle sont les applications “navigateur de données” : leur seule tâche est de permettre à l'utilisateur de naviguer dans les données, et ces applications traitent des familles entières de formats de données, car tout ce qu'elles ont à faire avec celles-ci c'est au minimum, un peu de coloration syntaxique, ou tout au plus, de la validation du type de données. Elles n'interagissent pas “en profondeur” avec les données, ce qui explique pourquoi elles peuvent traiter des données de n'importe quel domaine - le domaine des données n'a tout simplement rien à voir avec les fonctionnalités de l'application. Malgré tout, même ces applications ne pourront apprendre à lire des données aux formats JSON, malgré que le format soit conforme et auto-descriptif, si elles ont été conçues pour lire des données aux formats xml.

Adresses URI avec dièse et adresses avec 303

Il y a une école dans l'architecture web (je la nomme toujours en plaisantant à demi-mots l'école du “purisme de l'URI”) qui stipule que chaque fois que vous utilisez une URL comme un URI (par exemple, pour désigner un concept), alors vous ne pouvez pas appeler cela une URL (vous devez appeler cela soit URI ou URN), et elle devrait posséder, soit un dièse ('#'), ou soit répondre avec un code d'état 303. Je ne vois pas l'intérêt de cette règle ; Tout le monde, en dehors des tenants de ce “purisme de l'URI” utilise simplement les adresses URL sans ces complications àmha aléatoires, ce qui est beaucoup plus simple et fonctionne tout aussi bien.

Je ne fais que mentionner cela ici par souci d'exhaustivité, non pas comme une réelle recommandation de ma part. :)

Concevoir chaque convention indépendamment

Pour un programmeur, il n'existe souvent pas de plus grand bonheur que d'inventer quelque chose à partir de zéro. Essayer de trouver la solution globale ultime à un problème est amusant.

Nous avons déjà vu ce sujet dans l'épisode 1 ; Face aux problèmes liés au caractère fermé des sites de réseau sociaux, la plupart des programmeurs entreprennent de construire, à partir de zéro, un système SNS (“Social Networking Service”) ouvert.

Mais ce n'est pas ainsi que nous ne devrions développer la plate-forme web. Le web est extensible, et nous devons y ajouter des petits éléments bit-par-bit, en laissant chacun d'eux gagner ou non leur adoption, en fonction de ce qu'ils font.

Cela rend le développement de la plate-forme web un peu plus difficile que de développer une plate-forme fermée. Dans le même temps, ce cheminement conduit à un résultat plus robuste.

Pour rendre cela plus clair, je vais vous donner deux exemples. Tout d'abord, supposons que nous voulions permettre aux utilisateurs d'une application basée sur remoteStorage de choisir eux-mêmes leur avatar, et d'afficher les avatars de leurs amis. Nous pourrions par exemple ajouter les méthodes setAvatar() et getAvatar(). Ensuite, nous soumettons cet ajout en amont au module remoteStorage.profile, et ainsi, d'autres applications basées sur remoteStorage pourront alors utiliser les mêmes avatars indépendamment de l'application utilisée.

Mais nous pouvons faire encore mieux : nous pouvons utiliser l'avatar affiché dans les profil webfinger des utilisateurs. Par ce biais, le système de gestion des avatars utilisé se retrouve aussi indépendant de remoteStorage qu'une API de stockage spécifique.

L'autre exemple que j'aimerais vous donner concerne la séparation existante entre les formats de données et les protocoles d'interaction. Par exemple, un document ActivityStreams peut être publié dans un flux Atom ou de bien d'autres façons, et de la même manière, il existe de nombreux autres formats de données qui peuvent être utilisés pour publier des données par le biais d'un flux Atom ; Ce sont là deux éléments de construction totalement indépendant et interchangeable. Cette flexibilité est ce qui rend parfois l'utilisation du web chaotique comme plate-forme applicative, mais en définitive, celle-ci est aussi ce qui le rend très décentralisé et robuste.

Le Web en lecture-écriture

Nous pouvons reprendre l'exemple des avatars du dernier paragraphe et le pousser un peu plus loin. En ajoutant un lien pointant vers leur fichier webfinger à un document public sur leur compte remoteStorage, les utilisateurs peuvent même modifier leur avatar en utilisant remoteStorage. Nous avons ajouté le support des en-têtes Content-Type au fichier draft-dejong-remotestorage-00.txt tout spécialement pour que les données d'un compte utilisateur RemoteStorage puissent être des données pleinement “sur le réseau” (“on the web”) et ce, dans tous les sens du terme, et de rendre ce genre de choses possible. Il transforme le compte remoteStorage de l'utilisateur en un site web “accessible en lecture-écriture” (“read-write web” site) : un site Web, dont le contenu peut être édité depuis son interface http normale primaire, en utilisant des verbes autres que GET (dans notre cas, PUT et DELETE).

Le balisage sémantique

Il y a une dernière chose que je tiens à mentionner à propos de l'architecture de l'Internet : les documents primo lisible par l'homme, mais aussi partiellement lisible par les machines. Chaque fois que vous publiez un document lisible par l'homme, il est de bonne pratique d'ajouter des liens exploitables par la machine à l'intérieur du code html. Cette page, par exemple, a un lien vers le flux Atom de cette série de blog, et un lien vers mon propre site Web indépendant exploitable par une machine, avec un lien-relation d'“auteur”(rel="author").

Cela signifie par exemple que si vous avez le bouton “S'abonnerd'installé dans votre barre d'outils Firefox, vous verrez qu'il devient actif, et votre navigateur sera en mesure de trouver le flux atom exploitable par les machines sur lequel sont publiés les mises à jour de ce blog. De plus, les moteurs de recherche et autres sites Web “méta” peuvent afficher les méta-données d'une page Web simplement en analysant ces petites notes exploitables par les machines depuis le code html. Google fournit également des instructions sur la façon de marquer les recettes afin qu'elles deviennent consultables de manière “approfondie”.

En tant que développeur d'applications web unhosted vous aurez probablement à vous occuper davantage de documents déjà primo exploitable par les machines, mais c'est une notion importante qu'il faut connaître ; un document sur le web peut, dans un même temps, faire partie des documents web lisibles par l'homme et des données exploitables par les machines.

Conclusion

La souplesse de l'architecture associative de “Web linking” est une part essentielle de sa puissance en tant que plate-forme, mais aussi et surtout c'est ce qui donne au web son ouverture. Le web est ce que les gens font dans la pratique. Certaines technologies auront besoin du soutien des éditeurs de navigateur, dans le cas ou, pour l'exemple, il adviendrait que Firefox et Chrome mettent chacun en œuvre leur version d'une fonctionnalité, ils devront comparer leurs notes, choisir une version standard de cette fonction, et la documenter de manière à ce que les autres navigateurs puissent eux aussi la mettre en œuvre.

Pour les fonctions qui ne nécessitent pas de changement dans le fonctionnement des navigateurs, n'importe qui peut littéralement essayer de démarrer une convention, blogger à ce sujet, et essayer de convaincre d'autres personnes rencontrant le même problème à le rejoindre. C'est un système véritablement ouvert.

Commentaires bienvenus!

Suivant: app hosting (traduction en cours)