Cómo soportar diferentes versiones de API

15

Estoy escribiendo una API Rest y me pregunto cómo manejar mejor el soporte de las diferentes versiones. Con esto no me refiero a cómo definir un URI como V2 o V3, sino cómo estructurar el código dado que necesitaría:

  • Soporta múltiples versiones al mismo tiempo, por ejemplo. Los URI V1 y V2 y V3 deben estar activos al mismo tiempo. Retiraría V1 cuando digamos que V4 entra para restringir la cantidad admitida en cualquier momento.
  • Evite la mayor duplicación de código posible
  • Facilite la adición de cambios sin interrupciones a una versión, sin que afecte a otras versiones

Parece que hay pocos enfoques que podrían adoptarse:

  • Use Git para controlar las versiones, con una rama para las diferentes versiones (y las versiones antiguas esencialmente no tienen ningún nuevo trabajo de desarrollo realizado). Esto significaría que no hay duplicación de código, ya que solo la última versión está en el código, pero las versiones anteriores tendrían que funcionar con la nueva versión de la base de datos hasta que se retiren.

  • Duplique el código para que cada versión se maneje en la misma aplicación y tenga una ruta de código totalmente separada, pero esto significaría mucha duplicación

  • Reutilice una gran cantidad de código en las versiones, pero esto haría que sea más difícil de mantener, ya que cambiar una versión es más probable que afecte a una versión anterior

¿Existe alguna práctica recomendada para tratar este problema ya que todas las opciones parecen tener sus propios problemas?

Andy Davies
fuente
1
Si especifica el número de versión en la URL (por ejemplo, myserver / api / 3.1.4 / user / get), puede pasar el número de versión a cualquier función que llame para poder localizar el comportamiento específico de la versión sin compartir demasiado código.
James McLeod

Respuestas:

5

Hacer esto:

Reutilice una gran cantidad de código en las versiones, pero esto haría que sea más difícil de mantener, ya que cambiar una versión es más probable que afecte a una versión anterior

pero no rompas las versiones anteriores.

Debería realizar pruebas que verifiquen que todas las versiones compatibles funcionan correctamente. Si no tiene esas pruebas, primero debe crearlas para cubrir cualquier código que esté cambiando.

Kevin Cline
fuente
2

Una combinación de usar ramas de lanzamiento GIT (o bifurcar cada versión en un repositorio separado) para admitir y mantener versiones antiguas de API y posiblemente tener algún código reutilizable que pueda compartirse como una dependencia, como una biblioteca común, es muy probable que sea la forma ir. Por lo tanto, cada versión de API sería un artefacto desplegable por separado. Esto permite flexibilidad para que, por ejemplo, API V1 pueda depender de commons V1, mientras que APIs V2, V3, V4 pueden depender de commons V2. Esto sería lo más fácil y claro desde una perspectiva de desarrollo, ya que su base de código no se multiplica con cada nueva versión, sino que cada versión está aislada en su propia base de proyecto / código y solo se preocupa por sí misma.

Otra razón para implementar artefactos separados es que puede haber problemas transversales como un mecanismo de seguridad, o marcos / bibliotecas como su marco de inyección de dependencia que podría cambiar en las versiones más nuevas de la API y crearía muchas dificultades para admitir API más antiguas si todos viven en la misma base de código (y Classloader en tiempo de ejecución, si es Java).

Cada enfoque, ya sea una rama por versión o una base de código duplicado monolítico, siempre tendrá el problema de un punto de integración común (como el DB o un esquema de caché distribuido) que necesita cambiar. Las API de versiones anteriores pueden requerir algún tipo de mantenimiento para trabajar con esos cambios, o la introducción de algunas otras herramientas (como vistas de bases de datos) para ayudar a la compatibilidad. Esto puede ser una dificultad inevitable dependiendo de la naturaleza de sus cambios.

PaulMooney
fuente
0

No sé cuán diferentes son los resultados de las versiones de su API, pero podría tener una capa de compatibilidad en el medio que puede alternar entre las versiones y rellenar huecos o traducir datos.

Dicho esto, generalmente nunca funciona uno a uno, por lo que un diseño de interruptor o de máquina de estado me ha ayudado con este problema.

Zach Leighton
fuente