top of page
  • Foto del escritorRan Isenberg

API sin servidor: generación automática de documentos OpenAPI y protecciones CI/CD

Automatización de CI/CD de OpenAPI
Automatización de CI/CD de OpenAPI

La documentación de API de alta calidad mejora la satisfacción del cliente. En mi publicación anterior, presenté los medios para generar documentación OpenAPI para API sin servidor con Powertools para AWS. Sobre esa base, este artículo profundiza en la automatización e integración perfecta de este proceso en nuestro flujo de trabajo de CI/CD.

En esta publicación, aprenderá cómo generar documentación OpenAPI para sus API sin servidor automáticamente, mantenerla sincronizada con su código y protegerse contra cambios que rompan la API.

 

Tabla de contenido

 

Resumen de la documentación de OpenAPI sin servidor

En la publicación anterior , presenté un método para generar documentación OpenAPI para API basadas en funciones Python Lambda, utilizando Powertools para AWS Lambda y Pydantic.

Generé una documentación OpenAPI para una API sin servidor que consta de una API Gateway y una función Lambda. Definí el esquema de carga útil de entrada HTTP y TODAS las posibles respuestas HTTP: sus códigos y la carga útil JSON completa con Pydantic. La utilidad de manejo de eventos de Powertool manejó la generación de la documentación.

Sirvió la documentación bajo un nuevo punto final de API: '/swagger.'

Utilicé mi proyecto de plantilla de libro de recetas de AWS Lambda y agregué compatibilidad con la documentación de OpenAPI. Automatizaremos este proceso y agregaremos automatizaciones de CI/CD adicionales al flujo de trabajo basado en acciones de GitHub de CI/CD del proyecto.


La activación del punto final '/swagger' dio como resultado lo siguiente:

API abierta
API abierta

Por si no lo sabías, el Cookbook es un proyecto de plantilla que te permite comenzar a trabajar con serverless con tres clics, y tiene todas las mejores prácticas y utilidades que requiere un servicio serverless de nivel de producción.

 

Generación de documentación de OpenAPI

Supongamos que enviamos nuestra documentación de OpenAPI a los clientes o la publicamos en el sitio web de nuestra empresa. La solución presentada en la sección de resumen, donde los clientes acceden al punto final '/swagger' de la API, no cumple con estos requisitos. Busquemos una alternativa.


Una posible solución es agregar una automatización que extraiga la documentación de OpenAPI del endpoint '/swagger' y la almacene en el repositorio de GitHub del servicio. Una vez que se haya enviado al repositorio, podemos enviarla a nuestros clientes o publicarla en el sitio web de nuestra empresa.

También se abre todo un mundo de automatización.

Presentaré el método de generación de documentación OpenAPI automatizada y dos barreras de seguridad automatizadas que debe agregar a sus procesos de CI/CD. Estas incluyen:

  1. Mantener el archivo de documentación local sincronizado con el código en todo momento.

  2. Error en una solicitud de extracción en el flujo de trabajo de CI/CD si incluye cambios que alteran la API.


Es importante tener en cuenta que estos conceptos y automatizaciones se pueden reproducir en cualquier marco de CI/CD, no solo en GitHub Actions, como se presenta aquí.

Comencemos extrayendo la documentación de OpenAPI y almacenándola en el repositorio de servicios de manera automatizada y repetible.


Automatizar la documentación de OpenAPI

Cuando un desarrollador actualiza el código API, también es necesario actualizar la documentación de OpenAPI, por lo que los desarrolladores deben ejecutar la generación de la documentación de OpenAPI como parte de su PR. Automaticemos este proceso.


Usaremos la función de punto final Swagger de Powertools para generar una documentación de OpenAPI en formato JSON. Ya es compatible; solo necesitamos implementar nuestro servicio y acceder al punto final.

Escribiremos un script en Python para generar el archivo JSON de la documentación de OpenApi.

Si recuerdas, el controlador de eventos de Powertool expone un punto final '/swagger' en nuestra puerta de enlace de API que carga una bonita interfaz de usuario de Swagger. Sin embargo, si enviamos una solicitud HTTP GET a '/swagger?format=json', ¡obtendremos nuestra documentación en formato JSON!

Todo lo que necesitamos hacer es que el script descargue ese archivo JSON llamando a ese punto final con el parámetro de consulta y lo guarde en una carpeta de salida.


Repasemos el flujo general del script:

  1. Encuentra la URL de la puerta de enlace de API. Usé una técnica en la que almacené la URL en las salidas de la pila bajo la clave 'SwaggerURL'. Generé el nombre de la pila usando una convención predefinida y obtuve su salida. El nombre de la clave de salida de la pila es un argumento de script y puedes usar cualquier clave que quieras. Muestro la creación de la salida de la pila en mi publicación anterior. Otra opción es pasar la URL como argumento al script.

  2. Descargue el archivo JSON. Envíe una solicitud HTTP GET a la URL con un parámetro de consulta '/swagger?format=json'.

  3. Almacene el archivo descargado en el destino de salida; el valor predeterminado es '/docs/swagger'.

  4. Ahora que tienes el archivo, confírmalo como parte de tu solicitud de extracción.


El script está completamente documentado y se puede encontrar aquí .

También puedes ejecutar el comando ' make openapi ' para generar el archivo y guardarlo en la carpeta 'doc/swagger'. Agregué este comando de makefile porque los makefiles nos permiten usar un comando más simple localmente en la terminal del IDE y en la tubería de CI/CD sin exponer la implementación interna (el script de Python), que podemos reemplazar y actualizar en cualquier momento; es simplemente una mejor experiencia de usuario.


En el proyecto Cookbook, prefiero guardar la documentación JSON en la carpeta 'docs/swagger' para poder cargarla en el sitio web de páginas de GitHub de mi proyecto . Las páginas de GitHub son una excelente manera de permitir que los clientes vean sus API, al menos para proyectos de código abierto.


Ahora que tenemos la documentación en nuestro repositorio de GitHub, podemos confirmarla y generar una versión actualizada cada vez que realicemos cambios en la API.

Vayamos un paso más allá con dos automatizaciones cruciales.

 

Acciones de GitHub y automatización de CI/CD

En esta sección se presentarán dos automatizaciones de CI/CD fundamentales para el proceso de documentación de OpenAPI. Supongo que puedes generar la documentación, ya sea mediante el proceso que presenté o de alguna otra manera.

Ambas automatizaciones ya forman parte del proceso de CI/CD de la plantilla del libro de recetas de AWS Lambda .


El código está sincronizado con la documentación

La primera automatización es crucial. Queremos asegurarnos de que nuestro archivo de documentación comprometido represente el estado real de la API y esté realmente sincronizado con el código. Si enviamos el archivo de documentación a los clientes o lo publicamos en línea, debemos asegurarnos de que siempre esté actualizado.

No siempre podemos esperar que los clientes utilicen el punto final '/swagger'; y en algunos casos, es posible que no queramos exponerlo.

Actualmente, si bien podemos generar la documentación y confirmar el archivo, los desarrolladores deben recordar actualizar la documentación y ejecutar el script presentado en la parte de automatización anterior. Si se olvidan, nuestro archivo confirmado no estará sincronizado. Los clientes de la API no apreciarán la documentación desalineada y la frustración que conlleva cuando las llamadas a la API no funcionan como se espera.


Podemos agregar un nuevo paso a nuestra secuencia de CI/CD donde, como parte de una solicitud de incorporación de cambios, validamos que la documentación confirmada esté sincronizada con el estado actual de la API. Primero implementaremos nuestra aplicación y, después del paso de implementación del servicio , podemos ejecutar esta comprobación de validación. Si recuerdas, generamos la documentación descargándola desde el punto de conexión '/swagger', por lo que primero debemos implementar nuestro servicio.


Repasemos una acción de GitHub que resuelve este problema para nosotros.

Es un paso simple que ejecuta un comando makefile.


Y aquí está la implementación del comando makefile en bash:


En la línea 6, utilizamos el script que presenté al principio del artículo para generar un archivo de documentación a partir del servicio implementado en la solicitud de extracción. Lo guardamos como '.openapi_latest.json'.

En la línea 7, comparamos el archivo confirmado (bajo './docs/swagger/) con el archivo que acabamos de generar. Si el desarrollador actualizó la API y olvidó actualizar la documentación (al ejecutar el comando makefile 'make openapi' que presenté en la sección anterior) en las líneas 10 a 13, la solicitud de incorporación de cambios fallará.

Como puede ver en la línea 11, los desarrolladores también pueden ejecutar 'make pr' antes de enviar su código. El comando se ejecuta automáticamente y repara todos los linters, formateadores y la generación de OpenAPI.

El makefile completo se encuentra aquí .


Como puedes ver, es súper simple pero efectivo. Nos aseguramos de que la documentación esté siempre sincronizada con la API que expone el código.

 

Prevenir cambios disruptivos en la API

La segunda automatización evita cambios importantes en la API. A veces, los desarrolladores cometen errores y realizan cambios importantes sin darse cuenta del impacto en sus clientes.

Un cambio importante es un cambio que puede requerir que realices cambios en tu aplicación para evitar interrupciones en tu integración - Documentación de la API de LinkedIn

Los cambios que rompen la API vienen en muchas formas (como se define en la Documentación de la API de LinkedIn ) :

  1. Cambios en las definiciones de permisos existentes

  2. Eliminación de un parámetro permitido, un campo de solicitud o un campo de respuesta

  3. Adición de un parámetro obligatorio o un campo de solicitud sin valores predeterminados

  4. Cambios en la funcionalidad prevista de un punto final. Por ejemplo, si antes se utilizaba una solicitud DELETE para archivar el recurso, pero ahora se elimina definitivamente el recurso.

  5. Introducción de una nueva validación

Cuando se trata de cambios en la API, siempre debemos esforzarnos por hacerlos de manera inquebrantable, y hay muchas formas de hacerlo, pero lo dejo para otra publicación.

Sin embargo, no quiero dejar nada al azar y espero que el revisor del código entienda que los cambios de código en el PR (solicitud de extracción) son cambios importantes.

Quiero que el PR falle automáticamente si hay un cambio importante.


Ahora que tenemos la documentación de la API como parte de la PR, la validamos y nos aseguramos de que esté sincronizada con el código del servicio, verificar si hay cambios importantes se vuelve mucho más accesible.

Después de la implementación, agregaremos un nuevo paso al proceso de CI/CD de nuestra PR.

Utilizaremos una acción de GitHub de código abierto, oasdiff-action , basada en la herramienta ' oasdiff .'

La herramienta acepta dos archivos JSON de OpenAPI, el básico y el "nuevo" (revisión), y busca diferencias. Si encuentra diferencias, comprueba si estas diferencias (cambios) entre las API son cambios importantes. En caso de que lo sean, el pipeline falla. Es así de simple.


Veamos la definición:

Comparamos el archivo openapi.json en la carpeta './docs/swagger' que contiene los cambios en nuestra documentación con el archivo fusionado actualmente en la rama principal del repositorio de GitHub.


Pongamos a prueba la utilidad.

Digamos que agregamos un nuevo parámetro predeterminado a nuestro esquema de entrada 'CreateOrderRequest': 'new_order_item_count.'

Añadir parámetro obligatorio: cambio radical
Añadir parámetro obligatorio: cambio radical

Este es un cambio radical clásico. Una mejor manera de hacerlo es establecer un valor predeterminado para 'new_order_item_count' o introducir una API v2 donde este campo sea obligatorio.

El desarrollador generará la nueva documentación y la acción de GitHub verificará si hay cambios importantes en el código fusionado actual.

Ahora, cuando se ejecuta este PR, obtendremos un error con la siguiente información:

Las relaciones públicas fallan debido a cambios radicales
Las relaciones públicas fallan debido a cambios radicales

El error es correcto; agregamos una nueva propiedad de solicitud requerida, que falló como se esperaba; ¡nuestra documentación y nuestros usuarios se salvan de un cambio radical!


Gracias, Afik Grinstein , por presentarme esta utilidad.

 

Resumen

Con esto concluye la segunda publicación de mi serie de documentación sobre OpenAPI y API sin servidor.

Creamos un script que genera documentación OpenAPI a partir del código de nuestros controladores Lambda y lo exporta; validamos que esté sincronizado con el código y nos aseguramos de que no produzca ningún cambio que altere la API.

Comments


bottom of page