La disruption joyeuse

Les gros titres fleurissent : « Les API : clef de voûte de l’open banking », « Les API au cœur de la transformation digitale », « De l’économie des applications vers une économie des API : une révolution est bien en marche ! ».

Mais, que sont ces fameuses API, les bolcheviks d’une nouvelle révolution heureuse, à la fois structure, moteur et objectif ?

Que sont ces êtres nouveaux et disruptifs, portés par les hérauts du transformisme ?

Une partie nous vient de la révolution numérique, avec l’explosion des capacités de calcul. Barbara Liskov (autrice du fameux principe de substitution) écrivait à ce sujet en 1979 dans Primitives for Distributed Computing :

Auparavant, des considérations économiques favorisaient le partage d’un unique ordinateur entre de nombreux utilisateurs et le travail du système d’exploitation concernait le support et le contrôle d’un tel partage. Cependant, la nécessité de partager une ressource unique et coûteuse est désormais moindre. Les avancées dans les technologies matérielles ont amenées de grandes économies de coût pour les processeurs et la mémoire. Une conséquence possible de réduction des coûts est une nouvelle organisation logicielle, où des sous-parties d’un programme résident et sont exécutées sur différents ordinateurs connectés en réseau. Nous appellerons de tels programmes des programmes distribués.

Une des premières raisons pour lesquelles les programmes distribués sont souhaitables est que les organisations utilisant ces programmes sont elles-mêmes distribuées. Par exemple, une affaire est divisée en plusieurs sous-divisions. Chaque division a ses propres responsabilités, et met en œuvre des procédures internes sur ses données internes. Cependant, ces divisions fournissent des services pour les autres, de telle sorte qu’il est nécessaire d’avoir de la communications entre elles. Ces divisions peuvent être proches physiquement, ou au contraire dispersées géographiquement.

Une vrai révolution

Cette révolution de la programmation distribuée consiste donc en la mise à disposition de services à d’autres sous-parties d’un programme, et par programme on ne parle pas d’une unité d’exécution mais l’ensemble logique de tous les traitements. Pour s’organiser dans le programme, il va falloir matérialiser quelque part la description de la structure d’échange avec ces services, quel formalisme nous a été apporté dans cette révolution ? Continuons la lecture pour le savoir : l’article prend pour exemple une application de réservation de vols ; la notion de gardien (guardian) utilisée désigne le protecteur du sous-ensemble applicatif qui expose des services :

Notre solution est d’envoyer les messages à des ports. Un port est une passerelle monodirectionnelle vers un gardien. Il peut y avoir plusieurs ports pour un seul gardien ; chaque port appartient à un gardien, et seuls les processus à l’intérieur du gardien peuvent recevoir des messages de celui-ci.

Les ports sont les seules entités ayant un nom global. Quand un gardien est créé, il fournit un ou plusieurs ports ; les noms de ces ports sont communiqués au processus qui les a créé. Les noms de ces ports peuvent aussi être envoyés dans des messages ; ceci implique que les messages peuvent être envoyés à ces ports depuis plusieurs sources différentes. Il est attendu que les ports fournissent une forme de zone tampon pour que les messages puissent être mis en file d’attente si nécessaire.


Les ports sont décrits par la description des messages qui peuvent leur être envoyés. Par exemple, un port pour l’un des gardiens régionaux peut être décrit comme suit :
port_régional = port[réserve(numéro_vol, id_passager, date)
      replies (ok, plein, liste_d_attente, pre_réserve, vol_inconnu),
   annule (numéro_vol, id_passager, date)
      replies (ok, non_réservé, vol_inconnu),
   liste_passagers (numéro_vol, date)
      replies (info (liste_passagers), vol_inconnu)]

Notez que chaque message de requête est appairé avec un message de réponse attendu. Ces parties replies sont en fait une description d’un argument additionnel du message : un port qui peut recevoir les réponses attendues. Cette syntaxe met tout simplement en valeur la nature requête-réponse de la relation. La partie replies est omise si le message n’a pas de réponse attendue.

L’entête d’une définition de gardien liste un ou plusieurs ports qui peuvent être utilisés avec une instance de gardien, par exemple :
gérant_régional = guardiandef() provides p: port_régional
    % définition d’un programme séquentiel à exécuter
    % quand une instance de gérant_régional est créée.
    % p est une variable locale à ce programme
    end gérant_régional

[…]
Les types de port et les entêtes de gardien permettent la vérification au moment de la compilation de tous les messages échangés.

Ici nous avons traduit le terme anglais « port » par le terme français « port ». L’étymologie de ce terme est assez intéressante, les dictionnaires Oxford nous disent : « Old English (in the sense ‘gateway’), from Latin porta ‘gate’; reinforced in Middle English by Old French porte. The later sense ‘opening in the side of a ship’ led to the general sense ‘aperture’. » Ce terme anglais de « port » a été retranscris dans le cadre informatique par « port » comme anglicisme, alors que nous aurions dû utiliser « porte », car c’est bien l’esprit de la porte qui transpire par ce « port ». Néanmoins, on voit que dans ce terme on trouve aussi le sens de passerelle (gateway), ce qui montre qu’on n’a pas juste l’idée d’un contrôle ponctuel, mais bien un passage.

Dépasser la résistance au changement

Et là le pékin moyen se demandera quelles sont donc les différences fondamentales entre les API Gateway d’aujourd’hui et ces notions de ports d’hier. Ne faisons pas durer le suspense inutilement, la réponse est très simple : il n’y en a pas. Cela mérite néanmoins quelques éclaircissements au milieu de la nuageuse tourbe conceptuelle issue du Web deux point zéro. Le terme API, pour Application Program Interface ou interface pour logiciel applicatif (qui a dérivé en Application Programming Interface ou interface pour programmation logicielle), est un terme assez récent, apparu selon les recherches de Joshua Bloch en 1968 dans Data structures and techniques for remote computer graphics par Ira W. Cotton :

Normalement, on désire que l’interface entre les logiciels applicatifs et le système soit réalisée à travers des appels de sous-routines de type FORTRAN.

Le système a été conçu pour être, pour l’essentiel, indépendant du matériel dans le sens où l’implémentation […] pourrait être recodée pour un matériel différent ou amélioré, tout en maintenant la même interface l’un envers l’autre et avec le logiciel applicatif

Le mot français « interface » est tiré directement du mot anglais « interface » qui signifie : « surface à la frontière entre deux parties de matière ou d’espace » ; par cette définition, une interface est immatérielle, elle est à la frontière entre deux réalisations.

Même si le titre de l’article contient le mot remote, nous ne sommes pas ici dans une logique de programmation distribuée : ce terme fait référence à l’accès distant à travers une interface graphique (un terminal) à une ressource centralisée. L’API est le nom que l’on donne au moyen logique pour utiliser un sous-programme, et l’on souhaite que cette API reste la même dans le temps, y compris dans le cas où le sous-programme est recodé, quitte à effectuer une nouvelle compilation (en particulier lors d’un changement de matériel). L’intérêt de cette notion d’API est celui de la contractualisation, l’API et sa documentation associée décrivent la sous-routine appelée, les paramètres entrant et sortant, et permettre d’avoir la garantie de la régularité de l’invocation de cette sous-routine dès la compilation.

Vers l’infini et au-delà

On voit donc que l’API est une notion liée à l’organisation de l’écriture des programmes, et pas une notion liée à leur exécution. En conséquence, le terme API Gateway ne peut désigner qu’une passerelle menant à… des éléments d’organisation de sous-programmes ? Une telle irrationalité, bien que commune dans le monde du fashionable IT (qui n’a jamais entendu d’absurdités telles que « architecture Web MVC », « API REST » / « API Rest », « l’architecture hexagonale est liée à l’inversion de dépendance », ou encore pire « REST avec JSON » ?), pose quand même question : quelle agence de communication a pu penser à un tel nom ? Force est de constater que trouver la réponse à cette question est difficile, à tel point que Wikipedia ne donne aucune origine à ce terme, sans doute issu par génération spontanée autour d’un vide Gartnerien. Ceci aurait pu être compréhensible pour un mot issu d’une langue morte, mais pour une expression plus récente que l’encyclopédie elle-même, c’est un peu déconcertant, et le reste des explications des pages considérées sont à l’avenant. Tout au plus peut-on subodorer que c’est une conséquence du lobbying anti-XML qui ne nous aura décidément pas donné une belle image de la probité intellectuelle dans le monde de l’informatique.

Comme tous les termes saccagés par les révolutionnaires de la disruption collective, API est destiné à rester en tant que mauvais synonyme de « service et une de ses API associée ». Pour sa santé mentale, il suffit de garder à l’esprit qu’une API Gateway est une passerelle vers des services et pas vers une API, et que l’API Management ne sert pas à gérer des API mais à inventorier des points d’entrée vers des services en y associant un contrat d’interface, tout en y mêlant des notions de politiques d’accès. Et pour la vérification à la compilation ? Ça n’a pas de sens dans le monde merveilleux des API : un programme n’a pas à être stable, il doit s’adapter à ces API qui changent en permanence, parce que « aujourd’hui le monde va plus vite qu’hier, mais moins que demain ». Décidément, le monde des API est en contradiction avec celui des API.

Note : cet article a été initialement publié sur le défunt blog tech.