Cómo validar APIs en un pipeline de CI/CD (2/2)

En la primera parte de la publicación sobre nuestra propuesta de validación de APIs dentro de un flujo de integración continua vimos cómo garantizar el cumplimiento del contrato mediante tests con Postman y Newman.

En esta parte veremos cómo conseguir los otros dos objetivos que se marcaron en el flujo de validación: por un lado, controlar los cambios que verdaderamente se están subiendo en una release mediante una librería de comparación de definición de APIs: swagger-diff. Y por otro, cotejar la calidad del contrato de nuestra API mediante la definición de reglas de calidad y la comprobación de su cumplimiento mediante la librería Speccy.

Comprobación de cambios a desplegar

Uno de los puntos claves en el gobierno e implementación de APIs es el control y la gestión de cambios entre versiones mediante la detección de modificaciones no retrocompatibles respecto los servicios que actualmente se están consumiendo.

Existen diferentes librerías que nos permiten de una manera automatizada la detección de cambios entre diferentes versiones de Open API Specification y, entre esos cambios, la identificación de aquellos que rompen el contrato actual.

La incorporación de este tipo de herramientas en un pipeline de integración continua nos sirve para:

  • Alertar sobre la ruptura del contrato desplegado en la versión actual respecto los cambios que incorpora la funcionalidad de la nueva versión que se está desplegando.
  • Incorporar la lista de cambios real que se incluyen en el despliegue y añadirlos al changelog de la release.

En el mercado hay diferentes librerías que ofrecen esta funcionalidad, en la siguiente tabla se muestran algunas de ellas:

Todas ellas ofrecen, a través de línea de comandos, la detección de cambios entre versiones de OAS. Luego, a nivel de integración en el pipeline, ninguna herramienta es mejor que otra, pero sí hay diferencias si comparamos el nivel de detección de cambios.

En la siguiente tabla listamos los cambios, especialmente los no retrocompatibles que se probaron entre dos versiones de OAS 2.0 con las dos primeras librerías y OAS 3.0 con la tercera librería para comprobar si los detectan o no. La última opción se descarta por falta de actividad y mantenimiento de la misma durante más de dos años.

Como se ve en la tabla comparativa, la segunda librería apenas detecta cambios relevantes, mientras que la primera y la tercera sí. Después, dependiendo de qué versión de OAS se utilice para definir los contratos, se puede hacer uso de una de estas librerías dentro de nuestro pipeline.

Si queremos comprobar los cambios entre dos versiones de OAS 2.0 podemos hacer uso de la primera librería. Con la cual podemos:

  • Comprobar todos los cambios entre las dos versiones del contrato API mediante el comando:

Un ejemplo de la salida del comando anterior sería la siguiente:

  • Comprobar si hay cambios no retrocompatibles entre las dos versiones del contrato mediante el comando:

Un ejemplo de la salida del comando anterior con cambios no retrocompatibles sería el siguiente:

En caso de que no existan cambios que rompan el contrato no se devuelve nada en la salida del comando anterior.

Si queremos comprobar los cambios entre dos versiones de OAS 3.0, podemos hacer uso de la tercera librería con la cual, además de detectar los cambios no retrocompatibles y listar todos los cambios entre versiones, permite obtener esa información en formato markdown y html. Aquí podemos ver el ejemplo:

Calidad del contrato

Otro punto clave es la normalización de los contratos definidos en nuestros Swagger para representar de una manera homogénea todas las APIs que forman parte de una organización y sus aplicaciones.

Si bien es cierto que el punto clave es definir el conjunto de buenas prácticas para conseguir esa homogeneización, también es cierto que la revisión para comprobar el cumplimiento de esas buenas prácticas es muy tedioso.

Otro aspecto a tener en cuenta es la medición de lacalidad de los contratos. Es complicado justificar que un contrato de una API sea bueno o malo, ya que se trata de algo muy subjetivo, pero la manera de hacerlo es transformando algo cualitativo en algo cuantitativo que nos ayude a medir esa calidad y el cumplimiento de la normas establecidas.

Con el objetivo de conseguir esa homogeneización de una manera automática y la medición de la calidad de los contratos desplegados de una manera cuantitativa nos ayuda Speccy. Speccy es un motor de reglas que nos permite validar la definición de APIs en formato OAS 3.0.

Está desarrollada en Node.js y su funcionamiento radica en verificar si el fichero de definición de API cumple una serie de reglas definidas en un fichero yaml denominado ruleset, con el objetivo de que las definiciones sean lo más consistente posible y cumplan con la estrategia de gobierno y sus buenas prácticas.

Speccy incluye por defecto dos rulesets predefinidos en la carpeta de ese mismo nombre:

  • El fichero default, en el que se definen algunas reglas básicas como por ejemplo:
    • Todos los parámetros deben contener una descripción.
    • Toda operación o método debe tener un identificador de la operación.
    • Toda operación o método debe contener un resumen o una descripción.
    • La url del servidor y los path no puede terminar con “/”
    • Etc.
  • El fichero strict, hereda del fichero default, es decir, incorpora todas las reglas anteriores más las definidas de forma específica en este fichero en el que por ejemplo se incluye:
    • Obligatoriedad de indicar información de contacto con: nombre,  email y URL.
    • Inclusión de descripción de los tags.
    • Etc.

Para verificar si un contrato cumple las normas configurados en un ruleset simplemente se ejecutaría el siguiente comando indicando el conjunto de reglas a chequear y sobre qué contrato hacerlo:

Un ejemplo de verificacion correcto sería el siguiente:

Un ejemplo de verificación que no cumple algunas reglas sería el siguiente:

Como se muestra en la captura, la salida de la ejecución del error que devuelve Speccy indica cual es la regla que no se cumple.

En este caso:

  • info-contact: indicando que no incorpora la información de contacto.
  • parameter-description: indicando que el parámetro created-from no tiene descripción.

Se pueden definir tantos rulesets como se deseen e incluir en ellos las normas que se necesite corroborar. Para hacerlo, simplemente hay que generar un fichero yaml que contenta las reglas a verificar siguiendo el siguiente formato para cada una de ellas:

  • name: nombre de la regla, debe ser descriptivo y único como hemos visto es lo que sale en los logs.
  • object: objeto de la especificación swagger sobre la que se realiza la acción o comprobación.
  • description: una descripción de la norma.
  • action: acción que se va a realizar sobre el objeto del Swagger. El conjunto de acciones que se admiten realizar sobre un objeto de OAS se pueden ver en el siguiente enlace. Quizá la más útil para comprobaciones complejas es el “pattern”.

Un posible ejemplo de norma no incluida en los rulesets por defecto, y que sería interesante incluir, por ejemplo, sería obligar a que se defina una descripción a nivel de método u operación quedando de la siguiente forma:

También es posible habilitar o deshabilitar una regla dentro de un ruleset o saltar una determinada regla mediante la línea de comandos con la opción –skip, seguido de la lista de reglas que no se quieren comprobar. Por ejemplo: –skip=”contact-properties,license-url”

Una posible lista de reglas a incorporar en la verificación de un contrato y que no se incluyen por defecto serían:

  • Comprobación de la notación del path: camelcase o snake-case según se haya decidido.
  • Comprobación de la notación de los atributos del cuerpo de la petición/respuesta: camelCase: camelcase o snake-case según se haya decidido.
  • Establecer una longitud mínima de descripción a nivel de path, parameter, query, recurso.
  • Establecer una longitud mínima de la descripción de la API.
  • Incluir ejemplos en todos los modelos.
  • Incluir siempre tags.
  • Comprobación del valor de la versión para que cumpla un versionado semántico.

Dentro de las ventajas de esta herramienta, además de la funcionalidad obvia que ofrece es que Speccy está disponible como un paquete de node, por lo que se puede ejecutar fácilmente en la línea de comandos y, al igual que ocurre con Newman, es fácilmente integrable en nuestro pipeline.

La desventaja de esta herramienta es que solo soporta versión OAS 3.0 no versión 2.0. Si se quiere ejecutar la revisión de calidad para definiciones de API en versión 2.0 es necesario incluir un paso previo que transforma la especificación de la versión 2.0 a 3.0, para lo cual podemos ayudarnos de la librería swagger2openapi.

Una posible idea para usar Speccy, además de incorporarlo a un pipeline de integración continua como en este caso, podría ser ofrecer las reglas configuradas en Speccy con una API que las recubra por encima para poder gestionar dichas reglas de una manera sencilla e integrable en diferentes puntos del ciclo de vida de los proyectos, ya que muchas de estas reglas son reutilizables y son agnósticas del proyecto en sí.

Una propuesta de pipeline

Nuestra propuesta consiste en incorporar las herramientas anteriores en diferentes stages del pipeline de Jenkins, que se ejecutará al incluir/cambiar una funcionalidad mediante una Pull Request al repositorio.

En dicho repositorio Git se almacenarán los siguientes archivos: contrato de la API OAS 2.0 o 3.0, colección Postman con los tests y los ficheros de las variables de entorno. En el momento en el que se suba un cambio mediante una Pull Request el flujo realiza los siguientes pasos:

  • Stage 1: ejecución de los tests de contratos configurados en la colección Postman con el fichero de las variables de entorno que se corresponde con el entorno que se quiere desplegar. En caso de que la ejecución de los tests con Newman sea correcta, se pasa al siguiente stage, en caso contrario se paraliza el flujo.
  • Stage 2: ejecución del comparador del contrato OAS de la versión a desplegar respecto la versión desplegada actualmente y marcar la release con los cambios detectados a modo changelog.
  • Stage 3: verificación de la calidad del contrato mediante Speccy. En este caso se puede configurar si se desea parar o no el despliegue en caso de no pasar el umbral de calidad, pero al menos si tener comprobado si lo pasa y las causas de no cumplirlo para solucionar lo que se detecte en una siguiente entrega.

Siguientes pasos

Este pipeline es solo una propuesta sujeto a mejoras y cambios según los objetivos que se marquen conseguir. Como posibles mejoras a incorporar en el flujo se pueden citar las siguientes:

  • En la etapa de test de contratos:
    • Elaborar algún tipo de desarrollo que permita la construcción de los JSON Schema y su incorporación a los test de una manera automática, sin tener que realizar el cambio a mano.
    • Desarrollar una utilidad que en el caso de que los tests no pasen se envíe una notificación a los emails pre-configurados con el informe de los tests para avisar del error.
  • En la etapa de detección de cambios:
    • Se podría intentar unificar una única librería que funcione tanto para versión 2 de OAS como para la versión 3.
    • También sería una mejora la modificación de estas librerías actuales mediante la modificación de las mismas para que detecten los cambios que ahora mismo no son capaces de identificar.
    • Añadir algún mecanismo de configuración para identificar el nivel de gravedad o no retrocompatibilidad entre los cambios detectados en función de las políticas de versionado de cada caso.
    • También sería interesante hacer una comprobación de los cambios con el versionado semántico del contrato para ver si la versión corresponde con los cambios introducidos o no. O, si se quiere, también es posible versionar de manera automática según los cambios incluidos en la definición de la interfaz de la API.
  • En la etapa de calidad del contrato con la inclusión de una lista detallada de reglas para garantizar el cumplimiento de las buenas prácticas definidas por la organización.

Referencias

Foto de noeliamartin

Ingeniero Superior en Telecomunicaciones. Inicié mi carrera programando servicios hasta llegar al mundo de las APIs. Actualmente trabajo en Paradigma en el departamento de Arquitectura dentro del área de API Management y gobierno intentando promover las buenas prácticas en diseño y desarrollo de las APIs.

Ver toda la actividad de Noelia Martín

Escribe un comentario