python - meaning - Admite mĂșltiples versiones de API en matraz
flask wikipedia (1)
Empecé a diseñar un servicio web RESTful con Flask y Python y me pregunto cómo sería compatible con múltiples versiones de API en el mismo proyecto. Estoy pensando en poner la versión de la API solicitada en la URL de esta manera:
/myapp/v1/Users
Después de un tiempo, quiero agregar otro punto final en la versión 1.1 de la API y mantener todo desde v1, que no cambió:
/myapp/v1.1/Users <= Same as in v1
/myapp/v1.1/Books
En v2, el punto de "Usuario" se modifica:
/myapp/v2/Users <= Changed in v2
/myapp/v2/Books <= Same as in v1.1
y así...
En cuanto a this pregunta, la forma más fácil probablemente sería algo como esto:
@app.route(''/<version>/users'')
def users(version):
# do something
return jsonify(response)
Pero me puedo imaginar que esto será más difícil de mantener con cada nueva versión de API. Por lo tanto, me preguntaba si hay alguna forma mejor (= más fácil de mantener y mejor estructurada) de lograr esto con Flask.
Soy el autor de la respuesta aceptada sobre la pregunta que mencionaste. Creo que el enfoque de /<version>/users
no es muy efectivo como dices. Si tiene que administrar tres o cuatro versiones diferentes, terminará con código de espagueti.
La idea nginx que propuse allí es mejor, pero tiene la desventaja de que tienes que alojar dos aplicaciones separadas. En aquel entonces, me olvidé de mencionar una tercera alternativa, que es utilizar un modelo para cada versión de API. Por ejemplo, considere la siguiente estructura de aplicación (muy simplificada para mayor claridad):
my_project
+-- api/
+-- v1/
+-- __init__.py
+-- routes.py
+-- v1_1/
+-- __init__.py
+-- routes.py
+-- v2/
+-- __init__.py
+-- routes.py
+-- __init__.py
+-- common.py
Aquí tiene una api/common.py
que implementa las funciones comunes que necesitan todas las versiones de la API. Por ejemplo, puede tener una función auxiliar (no decorada como una ruta) que responda a su ruta /users
que sea idéntica en v1 y v1.1.
El routes.py
para cada versión de API define las rutas y, cuando es necesario, llama a common.py
funciones de common.py
para evitar la duplicación de la lógica. Por ejemplo, v1 y v1.1 routes.py
pueden tener:
from api import common
@api.route(''/users'')
def get_users():
return common.get_users()
Tenga en cuenta la api.route
. Aquí api
es un plan. Tener cada versión de API implementada como un plan ayuda a combinar todo con las URL versionadas adecuadas. Aquí hay un código de configuración de aplicación de ejemplo que importa los planos de la API en la instancia de la aplicación:
from api.v1 import api as api_v1
from api.v1_1 import api as api_v1_1
from api.v2 import api as api_v2
app.register_blueprint(api_v1, url_prefix=''/v1'')
app.register_blueprint(api_v1_1, url_prefix=''/v1.1'')
app.register_blueprint(api_v2, url_prefix=''/v2'')
Esta estructura es muy buena, ya que mantiene separadas todas las versiones de API, pero la misma aplicación las atiende. Como beneficio adicional, cuando llegue el momento de dejar de admitir v1, simplemente elimine la llamada register_blueprint
para esa versión, elimine el paquete v1
de sus fuentes y listo.
Ahora, con todo esto dicho, realmente deberías hacer un esfuerzo para diseñar tu API de una manera que minimice el riesgo de tener que actualizar la versión. Tenga en cuenta que agregar nuevas rutas no requiere una nueva versión de la API, está perfectamente bien extender una API con nuevas rutas. Y los cambios en las rutas existentes a veces se pueden diseñar de una manera que no afecte a los clientes antiguos. A veces es menos doloroso acelerar la API y tener más libertad para cambiar las cosas, pero lo ideal es que eso no ocurra con demasiada frecuencia.