Aller au contenu
Nos produitsSur-mesureSites & boutiquesRéférencesWe AreBlogNous contacter
Apparence
← Tous les articles
· 7 min de lecture#architecture#produit#cas concret

Une application mobile posée sur une API qu'on ne maîtrise pas

O

Oussama

Développeur mobile

En bref

Comment construire une application mobile sur une API existante qu'on ne peut pas modifier ?

En traduisant les réponses de l'API en entités propres à l'application dès la frontière, plutôt qu'en laissant sa structure remonter dans les écrans. Le découpage domaine / données / présentation coûte quelques fichiers de plus et rend l'application insensible aux changements de format côté serveur. Sans cette traduction, une évolution de l'API devient une reprise de tous les écrans qui l'utilisaient.

L’application mobile LinkoSport n’est pas partie d’une page blanche. Le site linkosport.fr existait, avec son back-office, sa base et son API. La demande était d’apporter iOS et Android, en un seul code, branchés sur cet existant.

C’est une situation très courante et rarement décrite : l’application n’est pas maîtresse du contrat. Elle consomme une API conçue pour un site web, qu’elle ne peut pas faire évoluer à sa convenance et dont elle doit absorber les changements.

Voici comment nous nous organisons pour que ce ne soit pas un problème permanent.

Le réflexe coûteux : consommer l’API telle quelle

La façon la plus rapide de démarrer consiste à désérialiser la réponse JSON dans un objet, et à passer cet objet directement aux écrans. Ça fonctionne, et c’est même agréable pendant les premières semaines.

Le problème arrive au premier changement côté serveur. Un champ renommé, une date qui passe de chaîne à entier, un objet imbriqué qui devient un identifiant : chaque modification se propage dans tous les écrans qui affichaient ce champ. On se retrouve à corriger de la mise en page parce qu’un format a changé, ce qui est le signe qu’une frontière manque.

Le second problème est plus insidieux. Une API de site web renvoie ce qui arrange le site : des champs facultatifs partout, des valeurs nulles, des libellés déjà formatés. Si ces approximations remontent jusqu’aux écrans, chaque widget se met à porter sa propre logique de repli — « si le nom est vide, afficher le pseudo » — dupliquée à dix endroits, et divergente.

Traduire à la frontière

Nous découpons chaque fonctionnalité en trois couches, et la règle tient en une phrase : le JSON ne dépasse jamais la couche données.

  • La couche données connaît l’API. Elle sait que la réponse s’appelle ProfilResponse, que tel champ peut être absent, que telle date arrive dans tel format. Son travail est de produire une entité propre.
  • La couche domaine ne contient que ces entités et les contrats de service. Elle ne sait pas qu’une API existe. C’est du code pur, sans dépendance à un framework, donc testable sans réseau ni simulateur.
  • La couche présentation manipule des états et affiche des entités. Elle ne fait aucun appel réseau et n’a aucune connaissance du format serveur.

L’intérêt se voit au premier changement d’API : il se traite dans un seul fichier de la couche données. Les écrans ne bougent pas, parce qu’ils n’ont jamais vu le format qui a changé.

Le coût est réel et il faut l’annoncer : c’est un fichier de modèle en plus par entité, et une conversion à écrire. Sur une application de quelques écrans, c’est de la cérémonie inutile. À partir du moment où l’API appartient à quelqu’un d’autre, ça se rembourse au premier changement — et il y en aura.

Illustration Photo : domaine public (CC0).

Garder l’entité plus petite que la réponse

Une conséquence utile de cette frontière : l’entité n’est pas obligée de reprendre tous les champs de la réponse.

Une API de site web renvoie souvent beaucoup de choses, parce qu’elle sert plusieurs pages. L’application n’a besoin que d’une partie. Reprendre tout « au cas où » alourdit le modèle, oblige à traiter des valeurs nulles qui ne serviront jamais, et donne l’illusion que ces données sont utilisées.

Nous ne reprenons donc que ce qui est affiché ou nécessaire à une décision. Quand un besoin apparaît, ajouter un champ à l’entité prend deux minutes — bien moins de temps que d’entretenir pendant deux ans des attributs dont personne ne sait s’ils servent.

People Man Photo : William Stitt — licence CC0.

L’authentification, à traiter une fois pour toutes

Un sujet transverse qui mérite d’être réglé au tout début, parce qu’il touche chaque appel et qu’il est pénible à rattraper.

Sur mobile, un secret d’authentification ne se stocke pas n’importe où : il va dans le coffre du système — Keychain sur iOS, Keystore sur Android — et pas dans les préférences applicatives, qui sont lisibles sur un appareil compromis. Ça, c’est la partie qu’on sait d’avance.

La partie qu’on n’anticipe pas, c’est que l’API existante n’authentifie pas forcément comme on s’y attend. Ici, l’en-tête Authorization ne transporte pas l’identité de l’utilisateur : il porte un jeton d’accès à l’environnement, qui protège la préproduction dans son ensemble. Y placer le jeton utilisateur — le réflexe de tout développeur mobile — fait échouer l’appel avec un laconique « Token invalide ». L’identité, elle, passe par le cookie de session du site existant.

Autrement dit, l’API émet bien un jeton d’utilisateur, et ce jeton est inexploitable : la session par cookie s’impose. Ce n’est pas une élégance d’architecture, c’est un héritage — et c’est exactement le type de contrainte qu’une application posée sur un existant doit absorber sans le répercuter partout.

D’où l’intérêt de traiter l’authentification à un seul endroit, dans un intercepteur du client HTTP, plutôt que dans chaque appel. Le jour où le backend rendra son jeton utilisable, un seul fichier changera. Si la règle avait été dispersée dans les écrans, elle serait aujourd’hui gravée dans tout le code.

Un dernier piège, celui-là purement mécanique : une compilation de production lancée sans le jeton d’environnement part avec un en-tête vide, et toutes les requêtes échouent. L’erreur est silencieuse à la compilation et brutale au lancement. C’est le genre de chose qui mérite un script de compilation plutôt qu’une ligne de commande recopiée de mémoire.

Running People Photo : Braden Collum — licence CC0.

Ce qui reste douloureux, et qu’aucun découpage ne règle

Deux points sur lesquels la frontière ne protège pas, et qu’il vaut mieux poser en cadrage.

Ce que l’API ne sait pas faire. Si une donnée n’est exposée nulle part, aucune architecture ne l’invente. Nous tenons donc un document unique, adressé à l’équipe qui détient l’API, listant les endpoints manquants et les anomalies relevées en recette — avec, pour chacun, l’état d’avancement côté mobile.

Ce n’est pas un artefact de confort. Sur ce projet, plusieurs modules entiers — messagerie, notifications, espaces dédiés aux entreprises et aux collectivités — ont leur interface prête et aucun endpoint en face. Ils ne sont pas en retard de développement mobile : ils attendent une autre équipe. Sans ce document, la conversation dérive vers « l’application n’est pas finie », ce qui est faux et démoralisant pour tout le monde.

Le corollaire est une décision de périmètre que nous prenons rarement de gaieté de cœur : quand un module n’a aucun backend prévu — pas retardé, prévu nulle part — nous le retirons plutôt que de le laisser afficher du contenu factice. Une section qui ment est pire qu’une section absente ; elle sera testée, remontée en bug, et défendue en réunion.

Le nombre d’allers-retours. Une API pensée pour une page web renvoie parfois de gros objets, ou impose plusieurs appels pour composer un écran. Sur un mobile en 4G, ce qui était imperceptible sur un ordinateur devient une attente visible. Le découpage en couches aide à placer un cache au bon endroit, mais il ne compense pas une API bavarde. Là encore, cela se mesure tôt, sur un vrai réseau, pas en Wi-Fi de bureau.

Le test qui valide le découpage

Il en existe un, simple et rapide : écrire un test de la couche domaine sans rien simuler du réseau.

Si c’est possible — si la logique s’exécute sans client HTTP, sans jeton, sans simulateur — la frontière est au bon endroit. Si le test exige de simuler une réponse JSON, c’est que le format serveur a déjà fui dans le domaine, et qu’un changement d’API touchera plus que prévu.

C’est le contrôle que nous faisons avant de considérer une fonctionnalité comme terminée. Il ne coûte rien, et il révèle immédiatement les endroits où l’on a pris un raccourci sous la pression du planning.

À lire aussi

Vous cherchez qui peut construire votre application ?

We IT conçoit, développe et exploite des applications web métier depuis 2022, à Lyon et partout en France. Cadrage, développement, mise en production et RUN.