Versions et API

Réponses et cita­tions en réfé­rence au billet de Florian. Le texte n’a aucun sens indé­pen­dam­ment.

Note: On parle de version dans l’URL mais d’autres la mettent dans les entêtes de requête. Cela ne change fina­le­ment pas grand chose vis à vis de la discus­sion qui suit.

Ensuite, qu’est-ce qui est versionné ? Il y a l’ap­pli­ca­tion, l’in­ter­face, les formats de données, et les données elle-même.

Je ne comprends pas. Il y a l’ap­pli­ca­tion client, l’ap­pli­ca­tion serveur et l’in­ter­face entre les deux. S’il y a une inter­face c’est juste­ment pour que chaque appli­ca­tion soit indé­pen­dante dans son coin (tant qu’elle respecte l’in­ter­face).

Ceux qui me préoc­cupe dans l’API c’est unique­ment le chan­ge­ment de l’in­ter­face (le I de API). Après que ce chan­ge­ment soit au niveau du format des données, du proto­cole, du sens des données ou de quelles données sont renvoyées, cela m’est indif­fé­rent : Il y a eu chan­ge­ment, qui néces­site (ou pas) de mettre à jour les appli­ca­tions qui utilisent cette inter­face.

Et j’ajou­te­rai : Si le chan­ge­ment est rétro-compa­tible, mon contrat d’in­ter­face est respec­ter, donc fina­le­ment je n’ai pas « changé » mon inter­face du point de vue des appli­ca­tions. Je n’ai même pas besoin de l’an­non­cer et donc de parler de version. Je ne me préoc­cu­pe­rai donc dans la suite que des versions *incom­pa­ti­bles*.

Mais, dans ce cadre là, à quoi vous sert le numéro de version dans l’URL ? Globa­le­ment : à rien. Si ce qui compte est la version de l’ap­pli­ca­tion, alors les URLs n’ont pas besoin de version.

Quand tu réflé­chis à savoir s’il faut passer de v1 à v1.1 lors d’un chan­ge­ment rétro-compa­tible tu ne motives pas du tout le pourquoi. Ton appli­ca­tion est compa­tible ? restes en v1.

Mon problème c’est quand tu commences à consi­dé­rer qu’en consé­quence autant faire un /books plutôt qu’un /v1/books.

La ques­tion est de savoir ce que tu feras quand tu auras une version incom­pa­tible. Si tu as choisi /v1/books tu feras proba­ble­ment un /v2/books et ce sera compré­hen­sible et simple à gérer pour tout le monde. Si tu n’as pas prévu les versions tu vas avoir un /books et un /v2/books en paral­lèle, et là pour le coup ça va être clai­re­ment confus pour tout le monde.

Crédo perso : Il faut l’évi­ter le plus long­temps possible mais un jour tu fini­ras forcé­ment par avoir besoin d’un chan­ge­ment incom­pa­tible. Autant le prévoir aujourd’­hui.

le numéro de version des URLs n’a ici aucun sens,

Indeed, ce n’est pas son rôle. Le numéro de version (qu’il soit dans l’URL ou ailleurs) est là pour disso­cier deux appels et savoir ce que l’API doit répondre. On met habi­tuel­le­ment des numé­ros de version ou des dates parce que c’est plus simple et évite des incom­pré­hen­sions, mais l’im­por­tant est juste que l’ap­pel soit diffé­rent. Il ne s’agit pas de donner une infor­ma­tion ou du sens au client. Les v1 et v2 peuvent tout à fait être rempla­cés par des GUID opaques et sans aucun sens.

C’est d’ailleurs pour cela que les 1.x ne sont à mon avis pas perti­nentes. Elles dénotent des versions mineures, où juste­ment on devrait évoluer de façon rétro-compa­tible, même si ça coûte un peu plus cher. Et dans ce cas, pourquoi casser les URL ?

La rupture n’a de sens qu’en cas d’in­com­pa­ti­bi­lité, et dans ce cas tu fais simple­ment une v2. Faire la diffé­rence entre v1.2 et v2 dans les URL serait juste­ment faire porter un sens à cette infor­ma­tion alors qu’il s’agit juste d’un arti­fice tech­nique destiné à sépa­rer deux requêtes.

Oui, vous pouvez, mais par expé­rience, je pense que :

  1. Cela complique inuti­le­ment le déve­lop­pe­ment (augmen­ta­tion méca­nique du nombre de lignes et de tests)
  2. Les risques et compli­ca­tions sont multi­pliés par le nombre de versions à gérer
  3. Vous devrez sans cesse assu­rer que le nouveau code est capable de gérer toutes les versions, et donc les compor­te­ments
  4. Des soucis de perfor­mances peuvent être à prévoir
  5. Cela réduit consi­dé­ra­ble­ment les possi­bi­li­tés d’un chan­ge­ment d’ar­chi­tec­ture interne

Si l’objet est de dire que main­te­nir des versions paral­lèles coûte (plus) cher, alors oui : Il faut effec­ti­ve­ment véri­fier la compa­ti­bi­lité à chaque chan­ge­ment, main­te­nir poten­tiel­le­ment plusieurs codes, et en gardant la compa­ti­bi­lité on se contraint forcé­ment à ne pas tout chan­ger en big bang. Tout ceci est un peu indé­pen­dant de comment tu gères les versions.

(Par contre je ne vois pas où se situe le problème de perfor­mance, gérer deux URL qui pointent au même endroit c’est une problé­ma­tique très simple sans perte de perfor­mance ou main­te­nance exces­sive)

Mais c’est un peu une non-ques­tion pour moi. Je ne vois que deux alter­na­tives :

  • Ne jamais faire de chan­ge­ment, même compa­tible, auquel cas la ques­tion ne se pose pas ;
  • Lors du chan­ge­ment rempla­cer l’an­cienne version par la nouvelle et s’as­su­rer que tous les clients migrent exac­te­ment au même moment.

Dans tous les autres cas que je conçois (mais je peux en oublier), il faut forcé­ment s’as­su­rer de la compa­ti­bi­lité avec plein de versions, et main­te­nir cette compa­ti­bi­lité un moment, donc payer les coûts que tu annonces.

Person­nel­le­ment je n’ima­gines pas faire quelque chose de parfait au point de ne jamais avoir besoin de le faire évoluer, et de mon expé­rience je n’en­vi­sage pas lancer un chan­ge­ment au même moment que tous les clients.


Suite avec la seconde partie :

Oui, tout dépend toujours du contexte, mais pour le coup avoir un /books/type/novel et un /type/novel plus récent amené à rempla­cer le précé­dent est pour moi exac­te­ment ce qui est dange­reux.

Ce qui est à utili­ser n’est pas clair, l’uti­li­sa­teur va être amené à pana­cher les versions, avec poten­tiel­le­ment des résul­tats inco­hé­rents, et quand tu auras un histo­rique avec plusieurs migra­tions de ce type ça sera juste un enfer à main­te­nir.

Quant aux 301 pour faire passer vers la version suivante, c’est juste « non ». Soit le chan­ge­ment est compa­tible et dans ce cas on ne parle pas de migra­tion de version (on peut chan­ger l’URL, mais c’est un tout autre sujet), soit on parle de versions incom­pa­tibles et il est hors de ques­tion de redi­ri­ger des robots vers une ressource incom­pa­tible qui risque de corrompre des données de son côté. Si je coupe je mets une 410, au moins c’est clair.

Parler d’hy­per­mé­dia c’est bien, mais là aussi c’est un tout autre sujet. Tu parles de comment décou­vrir les URL, ça ne réponds pas du tout à la ques­tion de comment tu les gères de ton côté. Par contre oui, quand tu passes à la v2 tu passes tout à la v2. Permettre de pana­cher c’est faire durer ta v1 encore plus long­temps et t’ex­po­ser à des effets de bords diffi­cile à iden­ti­fier pour tes clients. Ta v2 est cohé­rente en elle-même, si un service de la v1 est utile, il sera dans la v2 (ou alors c’est que tu as décidé de le faire dispa­raitre). Sans comp­ter que les iden­ti­fiants ne sont pas forcé­ment les mêmes dans les deux versions.

Et à la fin de ton second billet on arrive à la ques­tion que j’avais : entête ou URL ?

Par contre :

  • Tu affirmes que le passage par l’en­tête permet de l’ha­bi­tuer à des mises à jour fréquentes sans en augmen­ter le risque. Je ne vois abso­lu­ment pas pourquoi, et cette affir­ma­tion n’est pas expli­ci­tée.
  • Tu dis que ça permet de n’en mettre qu’une partie à jour, mais je ne vois pas ici non plus en quoi le passage par l’en­tête est plus souple.

Alors vu qu’on a fait des jours de hors sujet, autant que je précise :

  • Au niveau tech­nique, est-ce que le passage par l’URL ou par l’en­tête est pus simple à gérer (à cause ou grâce aux proxy par exemple, ou dans le routage de l’ap­pli­ca­tion serveur, ou parce que certains langages/frame­works côté clients sont plus diffi­cile à mani­pu­ler dans un cas ou dans l’autre)
  • Au niveau humain, est-ce que l’un ou l’autre est plus facile à comprendre, à mani­pu­ler, est moins propice aux erreurs, à mettre en oeuvre
  • Au niveau archi­tec­ture, est-ce que passer par des URLs ouvre plus de portes ou au contraire amène des contraintes parti­cu­lières ?

Et pour tout ça je parle de problèmes ou faci­li­tés effec­ti­ve­ment rencon­trées, pas de litté­ra­ture ou concepts.

Au final là, je n’ai aucun élément qui me permette de faire mon choix

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *