Yo tengo:
Mi intención es que la aplicación del matraz (todo el código generado) solo debe manejar la asignación de la API REST real y el análisis de parámetros para que coincida con la especificación de la API codificada en swagger. Después de cualquier análisis de parámetros (una vez más, el código generado) debe llamar directamente a mi backend (no generado).
Mi pregunta es, ¿cuál es la mejor manera de conectarlos sin editar manualmente el código generado en python / flask? (La retroalimentación sobre mi diseño, o los detalles de un patrón de diseño formal que logre esto también sería genial; soy nuevo en este espacio).
Recién llegado del generador, termino con funciones de python como:
def create_task(myTaskDefinition): """ comment as specified in swagger.json :param myTaskDefinition: json blah blah blah :type myTaskDefinition: dict | bytes :rtype: ApiResponse """ if connexion.request.is_json: myTaskDefinition = MyTaskTypeFromSwagger.from_dict(connexion.request.get_json()) return 'do some magic!' # swagger codegen inserts this string :)
En el backend tengo mi lógica real:
def create_task_backend(myTaskDefinition): # hand-coded, checked into git: do all the things return APIResponse(...)
¿Cuál es la forma correcta de obtener create_task()
para llamar a create_task_backend()
?
Por supuesto, si hago cambios de última hora en mi especificación de swagger, tendré que actualizar manualmente el código no generado independientemente; sin embargo, hay muchas razones por las que me gustaría volver a generar mi API (por ejemplo, agregar / refinar la clase MyTaskTypeFromSwagger
, o saltear el código generado en git) y si tengo que editar manualmente el código API generado, entonces todo esas ediciones son arrastradas con cada re-generación.
Por supuesto que podría escribir esto con una gramática simple en, por ejemplo. pyparsing; pero si bien esta es mi primera vez con este problema, parece probable que ya se haya resuelto ampliamente.
Tuve la tentación de usar swagger-codegen
antes y me encontré con el mismo enigma. Todo está bien hasta que actualice la especificación. A pesar de que puede usar plantillas personalizadas, esto parece una gran cantidad de gastos generales y de mantenimiento, cuando lo único que quiero es una API de diseño inicial.
Terminé usando connexion en su lugar, que usa la especificación swagger para manejar automáticamente el enrutamiento, cálculo de referencias, validación, etc. Connexion se basa en el matraz, por lo que no debería preocuparse por cambiar los marcos o nada, solo obtendrá el beneficio de las porciones de que su aplicación se maneje automáticamente desde swagger en lugar de tener que mantener el código generado automáticamente.
El siguiente enfoque funcionó para mí:
creado tres directorios:
src
– para mi código, src-gen
para el código generado swagger, codegen
en el que he puesto un script que genera el servidor junto con algunos trucos. Copié todas las plantillas (disponibles en la comstackción de codegen/templates
) a codegen/templates
y codegen/templates
el controller.mustache
para referirme a src/server_impl
, para que pueda usar mi propio código. La edición utiliza el lenguaje de la plantilla por lo que es genérico. Aún así no es perfecto (cambiaría algunas convenciones de nombres) pero hace el trabajo. Entonces, primero agregue a controller.mustache
:
from {packageName}}.server_impl.controllers_impl import {{classname}}_impl
luego agrega en lugar de return 'do some magic!'
el seguimiento:
return {{classname}}_impl.{{operationId}}({{#allParams}}{{paramName}}{{^required}}=None{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
src
tiene un directorio server_impl
. server_impl
se pueda importar como un módulo python. cd ../src-gen/swagger_server/ ln -s ../../src/server_impl/ cd ../../codegen java -jar swagger-codegen-cli.jar generate \ -i /path_to_your_swagger definition.yaml \ -l python-flask \ -o ../src-gen \ -t ./templates cd ../src-gen/ python3 -m swagger_server
Por ahora estoy trabajando alrededor de esto haciendo la comstackción en estos pasos
'do some magic'
(esa es la cadena que devuelven todos los puntos finales del controlador generados) simplemente llaman a una función correspondiente en mi “backend” git format-patch
para hacer un parche de los cambios anteriores, para que cuando se vuelva a generar el código, la comstackción pueda aplicar los cambios automáticamente. Por lo tanto, puedo agregar nuevos puntos finales y solo tengo que codificar manualmente las llamadas a mi backend ~ una vez. En lugar de usar archivos de parches, podría hacer esto directamente escribiendo una gramática de análisis de py para el código generado y usando el código generado analizado para crear las llamadas a mi backend … eso llevaría más tiempo, así que hice todo esto rápidamente. cortar.
Esto está lejos de ser óptimo, no voy a marcar esto como aceptado ya que espero que alguien ofrezca una solución real.