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 e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *