Étiquette : API

  • The lie of the API

    Quelques réponses sur un billet qui a beau­coup circulé : The lie of the API.

    Ça flatte beau­coup la mouvance HATEOAS mais je n’ac­croche pas. Même avec des clients très smart, impos­sible de faire un même site pour les visites « navi­ga­teur » et les accès « API ».

    Le logi­ciel client de l’API ne sera jamais assez intel­li­gent pour comprendre autant le contexte que l’hu­main derrière son navi­ga­teur, et jamais assez souple pour gérer des chan­ge­ments non prévus.

    Donc partons de notre biblio­thèque qui expose des collec­tions avec des conte­nus, chacun reliés à des auteurs.

    Et si demain je change mes repré­sen­ta­tions pour ne plus mettre les bio des auteurs dans la fiche du livre direc­te­ment ? Certes tech­nique­ment il est possible de faire un robot qui sache récu­pé­rer cette bio sur la fiche de l’au­teur, mais quelle est la proba­bi­lité que les robots actuels gèrent le chan­ge­ment ?

    Et si demain le site web est changé pour que le point d’en­trée premier soit l’au­teur ? Le logi­ciel saura-t-il recher­cher un livre dont il ne connait pas l’adresse ?

    Et si demain je change le système de clas­si­fi­ca­tion des livres pour passer de BISAC à la CLIL française ? Quelle proba­bi­lité que le robot et l’ap­pli­ca­tif derrière gère ça de façon trans­pa­rente ?

    La partie desti­née au robot (qu’on nomme géné­ra­le­ment « API ») n’a simple­ment pas les mêmes besoins que la partie desti­née aux humains (qu’on nomme souvent « web »). On peut faire conci­lier les deux au début, mais ça va casser au fur et à mesure des évolu­tions de la partie desti­née aux humains.

    Tout ça pour quoi ? La satis­fac­tion intel­lec­tuelle du déve­lop­peur qui se dit qu’il corres­pond au schéma idéal du web. La valeur ajou­tée ne me semble pas justi­fier le risque.

    C’est d’au­tant plus vrai qu’en réalité les clients qui codent des robots hyper­me­dia corrects il n’y en a pas tant que ça. Rapi­de­ment des tiers vont coder des robots en faisant de l’in­gé­nie­rie inverse sur les adresses, les iden­ti­fiants, la struc­ture, les données. Ça sera peut être de leur faute, mais ça va casser si vous faites des chan­ge­ments en vous repo­sant unique­ment sur le côté hyper­me­dia.

    D’où la ques­tion : Souhai­tez-vous que ça fonc­tionne ou avoir raison ?

  • Défi­nir son API : version­ne­ment

    Toujours dans la logique de réflé­chir son API, parce qu’un jour il faudra la faire évoluer, comment gérer le version­ne­ment ?

    Plusieurs solu­tions ont émergé :

    • https://api-v2.example.com/mares­source
    • https://api.example.com/v2/mares­source
    • https://api.example.com/mares­source-v2
    • https://api.example.com/mares­source?v=2
    • https://api.example.com/mares­source avec une entête Version: 2
    • https://api.example.com/mares­source avec une entête Accept ou/et Content-type: appli­ca­tion/monfor­mat;version=2

    La solu­tion du sous-domaine n’est à mon sens à réser­ver que pour les big-bang. Elle n’est pas faci­le­ment multi­pliable à l’in­fini, mais à l’avan­tage de permettre aisé­ment d’avoir même deux plate­formes tota­le­ment sépa­rées pour les deux versions de l’API.

    Les deux suivantes se distinguent par le fait de version­ner l’API ou la ressource. J’ai tendance à penser que s’il faut version­ner la ressource en cassant la compa­ti­bi­lité, alors c’est peut être une nouvelle version de l’API qui est à publier si on ne veut pas finir avec un gros patch­work diffi­cile à main­te­nir : En gardant tout sous le même espace on s’in­ter­dit de faci­le­ment rendre obso­lète les anciennes versions.

    Quitte à parfois devoir version­ner au niveau de la ressource, l’idée d’ajou­ter un para­mètre a fini par me sembler plus propre. Il s’agit quasi­ment toujours de s’adres­ser à une repré­sen­ta­tion diffé­rente de la ressource, pas de chan­ger son sens fonda­men­tal. Le risque est que la plupart des gens conti­nuent à utili­ser la version d’ori­gine et ne pas prendre en compte le para­mètre. Rendre obso­lète des anciennes repré­sen­ta­tions risque là aussi d’être diffi­cile.

    Les possi­bi­li­tés d’ajou­ter les versions dans les entêtes sont souvent conseillées d’un point de vue théo­rique. En pratique mon retour est que c’est complexe à utili­ser, et d’une valeur ajou­tée assez discu­table. On oublie trop faci­le­ment que le bon usage de l’API tient direc­te­ment à sa simpli­cité et sa bonne compré­hen­sion. S’il y a besoin d’être expert en archi­tec­ture web pour comprendre le pourquoi des choses, c’est une mauvaise solu­tion. Le « tout dans l’URL » ajoute une faci­lité pour tester et échan­ger entre tech­ni­ciens qui vaut toutes les posi­tions acadé­miques du monde.

    Twilio a aussi une façon inté­res­sante de gérer les versions. Au lieu d’un v2 ou v3, le déve­lop­peur indique une date et c’est le serveur qui sélec­tionne la version de l’API à utili­ser en fonc­tion de la date. C’est tentant, souple, mais j’ai peur que ce ne soit pas suffi­sam­ment expli­cite sur ce qu’on utilise ou sur comment gérer ce para­mètre. Qu’est-ce qui change si je met à jour la date ?

    Des lectures et expé­riences je tire quelques recom­man­da­tions :

    • Prévoir dès le départ un système de version­ne­ment, vous en aurez besoin un jour, ne croyez pas que vos API pour­ront rester telles quelles ad vitam eter­nam
    • Impo­ser un version­ne­ment expli­cite, immé­dia­te­ment, dès la première version. Vous évite­rez les ambi­guï­tés et une partie des moules qui s’at­tachent aux adresses « sans version » par défaut
    • N’uti­li­ser que des numé­ros de version simples, pas de notion de mineur/majeur, pas de points ou virgules : Si ça change de façon non compa­tible c’est une nouvelle version et on incré­mente d’une unité. Le reste c’est du marke­ting et ça n’a rien à faire dans vos URLs.
    • Utili­ser un version­ne­ment dans l’URL, à la racine du service ; il sera temps d’uti­li­ser un autre sous-domaine si un jour il y a un vrai big bang qui le néces­site
    • Docu­men­ter (oui, c’est évident, mais pas si simple à ne pas oublier)
  • Défi­nir son API : authen­ti­fi­ca­tion

    Je lis le PDF gratuit de Apigee à propos du design des API web. Si les autres PDF gratuits du site sont assez creux, celui là pose de bonnes ques­tions qui font écho avec mes propres reflexions.

    Je le prends dans le désordre et pour reprendre mes erreurs passées ou celles que j’ai vu chez les autres :

    • Pas de système de session avec point d’en­trée spéci­fique pour le login. Ça demande au client de se préoc­cu­per de l’ex­pi­ra­tion de la session et de son main­tient. Pour des appels isolés ça veut dire faire deux requêtes (login + action) au lieu d’une, avec un délai de réponse finale allongé et une charge plus impor­tante pour le serveur. Sauf besoin spéci­fique, il faut rester en state­less : Chaque connexion contient ses propres infor­ma­tions d’au­then­ti­fi­ca­tion.
    • Pas d’au­then­ti­fi­ca­tion par IP, comme je le vois trop souvent. Outre que c’est un poten­tiel problème de sécu­rité, c’est juste quelque chose de diffi­ci­le­ment main­te­nable et c’est toujours au dernier moment quand on veut faire un correc­tif, une migra­tion ou une bascule vers le serveur de secours en urgence qu’on se rend compte du problème.
    • L’au­then­ti­fi­ca­tion HTTP Digest me semble être une mauvaise réponse à tous les problèmes. Pour amélio­rer légè­re­ment la résis­tance aux inter­cep­tions, il faut stocker le mot de passe en clair côté serveur. Une authen­ti­fi­ca­tion HTTP Basic avec du TLS pour sécu­ri­ser la commu­ni­ca­tion me semble bien plus perti­nent, et aussi plus simple à réali­ser.
    • Le système fait maison est toujours la pire solu­tion, même si vous pensez savoir ce que vous faites. C’est un NO GO commun à toute problé­ma­tique qui touche la sécu­rité. Vous avez plus de chances de vous tirer une balle dans le pied qu’autre chose, et pour le même prix ce sera toujours plus complexe quand vous commu­nique­rez avec des tiers.
    • OAuth 2 a la mauvaise idée d’être plus une boite à outils qu’une solu­tion finie. Même les gros groupes se prennent les pieds dans le tapis avec ça. On rejoint un peu le système fait maison. OAuth a ses défauts, mais globa­le­ment est une sphère contrô­lée que vous devriez préfé­rer.

    Au final il reste le choix entre l’au­then­ti­fi­ca­tion HTTP Basic, l’au­then­ti­fi­ca­tion par certi­fi­cat client avec SSL/TLS, ou OAuth 1.0. Ma grille de choix est la suivante :

    • OAuth s’il s’agit d’avoir une authen­ti­fi­ca­tion à trois pattes. Hors de ques­tion d’im­po­ser à l’uti­li­sa­teur final de saisir ses mots de passes dans un logi­ciel tiers. Pour une API qui veut créer un écosys­tème de logi­ciels clients (type twit­ter) c’est le choix quasi­ment imposé. Oui il y a des diffi­cul­tés pour le mobile ou pour ce qui n’est pas « navi­ga­teur », mais ces ques­tions sont désor­mais large­ment docu­men­tées. Pensez bien que choi­sir ce type d’au­then­ti­fi­ca­tion demande un réel travail (par exemple trou­ver l’er­go­no­mie pour permettre à l’uti­li­sa­teur d’au­to­ri­ser et reti­rer l’au­to­ri­sa­tion d’ap­pli­ca­tions tierces sur votre propre système)
    • HTTP Basic par défaut pour quasi­ment toutes les autres situa­tions. C’est simple côté client, simple et maitrisé côté serveur, supporté partout et pour tout, suffi­sam­ment sécu­risé si on passe par du SSL/TLS.
    • Et les certi­fi­cats clients avec SSL/TLS ? C’est une solu­tion qui semble plus inté­res­sante que l’au­then­ti­fi­ca­tion HTTP mais qui se révèle complexe pour pas mal d’in­ter­lo­cu­teurs. La valeur ajou­tée ne semble pas valoir la complexité supplé­men­taire si vous n’in­te­ra­gis­sez pas avec des entre­prises de taille signi­fi­ca­tive. J’y croyais beau­coup, mais fina­le­ment j’ai peu d’ar­gu­ment face à la simpli­cité du HTTP Basic.

    Et vous ? vous utili­sez quoi pour l’au­then­ti­fi­ca­tion de vos services ?