Mettre à jour une application mobile sans passer par les stores - #4 Server-Driven UI

Et si on poussait le concept de Backend for Frontend encore plus loin, à l’extrême ? Un peu à l’image de l’Extreme Programming qui pousse des pratiques dans leurs retranchements. Qu’est-ce que ça pourrait donner pour notre histoire de backend et de front mobile ? Pourrait-on déporter jusqu’à l’UI de l’application ?

De base, notre backend stocke des données, communique avec d’autres services et applique de nombreuses règles métiers. Notre application, elle, va envoyer une requête pour récupérer des informations, les traiter, appliquer d’autres règles, puis construire un rendu visuel avec divers composants UI (j’ai une bannière, ensuite un carrousel avec trois images, puis une liste d’articles).

On a vu qu’on pouvait ajouter des traitements spécifiques au mobile en ayant un Back for Frontend. Ça nous aide en déportant certaines règles côté backend, en agrégeant des données de plusieurs sources, en facilitant certains changements. Reste encore à construire le rendu visuel côté application.

On en arrive au cran d’après. Bienvenue dans le Server-Driven UI.

Je te dis comment afficher

Avec du Server-Driven UI (aussi appelé Server-Driven Rendering, Backend-Driven UI, …), il y a un backend qui va à la fois retourner des données ET indiquer comment les présenter. Une partie de la construction de l’interface graphique (du front mobile) est déportée côté backend.

Qu’est-ce que ça veut dire, construire l’interface ? Eh bien, le backend indique les composants à afficher (une bannière, un carrousel, une liste d’éléments, une image, …) directement renseignés avec les données associées. De fait, la composition de l’écran est aussi gérée (j’ai d’abord la bannière, ensuite le carrousel, …). Et il pourrait aussi configurer les composants (le texte de la carte est bleu, la police de 16pt, …), les actions lorsque l’on tape sur un élément.

La réponse à une requête sera beaucoup plus riche. Un exemple au format JSON :

{
    "title": "Accueil",
    "content": [
        {
            "type": "carousel",
            "content": [
                {
                    "image": "https://monserveur.com/img/001.jpg",
                    "text": "Arthur",
                    "color": "#FFFFFF"
                },
                {
                    "image": "https://monserveur.com/img/002.jpg",
                    "text": "Perceval",
                    "color": "#FFFFFF"
                },
                {
                    "image": "https://monserveur.com/img/003.jpg",
                    "text": "Lancelot",
                    "color": "#FFFFFF"
                }
            ]
        },
        {
            "identifier": "list",
            "content": [
                {
                    "title": "Les personnages",
                    "description": "En découvrir plus sur les personnages",
                    "details": "88026897-3fcb-4de8-af77-9aeb76d1e8a1"
                },
                {
                    "title": "Les secrets de tournage",
                    "description": "Mystère et magie !",
                    "details": "1da6005c-1f57-4c95-bb1a-6fb3b3a1bde7"
                }
            ]
        }
    ]
}

On obtient donc un nouveau moyen de mettre à jour une application mobile sans passer par les stores. On peut contrôler la construction de l’affichage à distance. Ça nous intéresse car ça nous ouvre des portes pour expérimenter, pour changer plus vite.

Tout cela implique un développement côté serveur et côté application.

  • Côté serveur. Il y a une brique / un service / un backend qui construit cette réponse plus complexe. Qui doit avoir cette logique de présentation des données.
  • Côté application mobile. Il faut créer chaque composant et il faut une brique qui interprète la réponse du serveur pour la traduire dans les composants correspondants.

Et vu que c’est à notre portée, on peut aller aussi loin que nécessaire pour répondre à notre besoin. On peut avoir une présentation plutôt simple. Le serveur indiquerait seulement des composants à afficher avec leurs données. Ou au contraire, on peut pousser la configuration en détaillant des tailles de texte, des couleurs, des alignements, etc.

On a également le choix d’appliquer ce concept dans les parties de l’application qui nous intéressent. On peut avoir du Server-Driven UI uniquement sur une sous-partie de l’application. Ce n’est pas structurant au point de nécessiter d’en avoir partout. Mais on peut le faire, s’il y a le besoin. On adapte !

Quelques cas - exemples

Pour illustrer et donner de l’inspiration, voici des cas qui existent en production sur des applications grand public.

Une campagne de satisfaction. Sous la forme d’un simple formulaire, avec une suite de questions et plusieurs formats de réponses (choix multiple, choix unique, champs de texte libre). La complexité technique et fonctionnelle est faible. Il ne s’agit que de donner des questions et d’indiquer sous quelle forme on peut y répondre. Il y a un besoin de déclencher une campagne à n’importe quel moment et de moduler le contenu.

Un quizz. On est dans le même ordre d’idées, c’est au final une sorte de formulaire mais présenté sous une autre forme. Ici, le besoin est d’avoir un parcours de questions qui change régulièrement, sans pour autant faire de mise à jour.

Un onboarding. On entre dans un parcours bien plus complexe et lourd. C’est une succession d’écrans avec de nombreuses possibilités comme des formulaires, des listes, des présentation de CGU, de l’upload de fichier, de la visualisation d’images, etc. Les formulaires sont complexes, contiennent des règles de validation, possèdent plusieurs formes (champs libres, choix multiple, champs numéro de téléphone, …). On peut ajouter des boutons et des popups d’aide / assistance. Bref, un parcours complètement modulable car il y a un fort besoin de changement. À l’autre bout, un back-office existe pour configurer tout cela.

Une page d’accueil. Pas de parcours mais une composition de page qui nécessite d’être très modulable. Un jour une simple liste, un autre jour une mise en avant avec une bannière et un el suivi de la liste. Parfois des raccourcis, des cartes d’action rapide. D’autres fois des rappels. Et demain, un peu de tout ça en même temps. D’ailleurs, on expérimente facilement ce qui marche le mieux en changeant à distance l’interface.

Un fil de contenu. Dès lors que le contenu est très dynamique, sa présentation l’est aussi. On a besoin d’adapter les formats.

Bénéfices

Outre la gestion de l’affichage déporté sur un serveur, on peut espérer obtenir d’autres avantages grâce au Server-Driven UI.

Déjà, et c’est ce qui nous intéressait le plus par rapport à notre histoire, à cette série d’articles, on peut changer de nouveaux éléments de notre application mobile sans devoir passer par les stores : l’interface graphique.

Et on est plutôt ravi de cette possibilité. On va pouvoir changer à distance plus profondément l’application, on va pouvoir apporter des changements et des corrections plus rapidement aux utilisateurs. On aura plus de contrôle.

On facilite également l'expérimentation, l’A/B Testing. Pas besoin de Feature Flag, c’est un serveur qui génère la composition de l’écran. C’est déjà de la configuration à distance. On peut donc dès maintenant expérimenter.

Si plusieurs plateformes consomment notre serveur, on gagne une unification des interfaces. Le serveur devient une source de vérité unique, les applications clientes ne feront qu’appliquer la présentation reçue. On a plus facilement une cohérence entre différentes plateformes. Le changement de l’affichage ne se fera qu’à un seul endroit.

Points d’attention

Comme d’habitude, rien n’est magique ou parfait. Le Server-Driven UI ne fait pas exception.

Je commence par enfoncer une porte ouverte. Si on veut que notre serveur retourne un nouveau composant, ou une nouvelle configuration par exemple, il faut le code de notre application puisse l'interpréter. Il faut donc soumettre une mise à jour de l’application pour gérer ces nouveaux cas. Comme si on ajoutait une nouvelle Feature Flag.

Je continue avec une autre porte voisine, les versions. Il faut garder en tête que dans la nature, il y a possiblement une grande variété de versions de notre application. Eh oui, pour rappel, rien n’oblige un utilisateur à mettre à jour une application mobile. Il la fera peut-être rapidement, ou dans une semaine, ou jamais.

On a donc une problématique de rétrocompatibilité. Admettons qu’on ajoute un nouveau composant et qu’on ait une nouvelle version de l’application qui le gère, comment ça se passe pour les anciennes applications ? On peut versionner nos composants. On peut créer un mécanisme de mise à jour forcée. On peut ignorer. On a plusieurs options, mais il faut y penser.

Le Server-Driven UI, c’est également une couche supplémentaire dans notre système. Ça vient avec son lot de complexité, de besoin de maintenance, de debug, etc. Et ça requiert un investissement à l’entrée. Il y a un coût de développement plus élevé au début pour mettre en place les différentes briques et composants pour que tout fonctionne.

Je pense aussi à la sécurité. La surface d’attaque de l’application est augmentée puisqu’elle se base davantage sur des instructions extérieures. Il est facile de modifier à la volée une réponse HTTP. Par exemple, si le serveur indique des intentions de navigation ou d’action, l’application devrait peut-être vérifier que l’utilisateur a bien le droit de le faire.

Pour se lancer

Le sujet du Server-Driven UI étant vaste et complexe, on peut chercher à en apprendre plus en s’inspirant de retours d’expériences de grands noms qui en font ou qui en ont fait de manière poussée : AirBnb, Instagram, Lyft, Reddit, Square.

On peut aussi regarder du côté de frameworks qui existent déjà. En faisant une rapide recherche, je tombe sur DivKit et beagle qui proposent des solutions à la fois côté serveur et côté client iOS, Android, web. J’avais également repéré rfw (Remote Flutter Widget), mais qui me semble d’ailleurs plus proche d’un interpréteur de code. On le verra peut-être dans l’épisode suivant !


Série d’articles Mettre à jour une application mobile sans passer par les stores :

Hors-série :

  • Accélérer le temps de review App Store d’une application iOS
  • Forcer la mise à jour d’une application mobile