OpenAPI v3

Introducción
En esta ocasión nos vamos a centrar en las principales diferencias entre OpenAPI v3 y swagger, nombre con el que se conoce la v2. Asumimos, por tanto, que se tienen ciertos conocimientos en swagger y/o se ha leído el blog anterior, en el que se habló de OpenAPI v2 entre otras cosas.
Estructura del documento de definición con OpenAPI v3
OpenAPI
Sustituye a la etiqueta swagger de OpenAPIv2. En la versión 2 la etiqueta swagger siempre se cumplimentaba con valor ‘2.0’. En el caso de la versión 3 tenemos 4 subversiones, con escasas diferencias entre ellas. Estas son 3.0.0, 3.0.1, 3.0.2 y 3.0.3. En la documentación de OpenAPI se dice que son funcionalmente la misma.
Info
Este objeto es el mismo que en la versión anterior, por lo que no incidiremos más en el mismo.
Servers
Este elemento es una mejora sustancial con respecto a OpenAPI v2. En swagger sólo se puede especificar un host, lo cual provoca que haya que modificar el mismo en función del entorno para el que se va a usar la definición. El elemento servers es una lista de hosts que pueden alojar la interfaz. Se definen mediante dos propiedades: url y description. Esta estructura nos permite indicar la URL del host e indicar a la vez a que entorno pertenece. En la documentación se visualizan como un combo en el que se puede seleccionar el host deseado.
Este elemento agrupa y hace innecesarios los elementos host, schemes y basepath. La URL base de cada host se especifica por completo en cada elemento del array de servidores. Como se pueden especificar tantos como sean necesarios podemos tener distintos protocolos, máquinas y contextos sirviendo la misma API.


Servers

Paths
Esta sección es prácticamente idéntica que en OpenAPI v2, a excepción de alguna diferencia que es lo que vamos a reseñar.
RequestBody
En swagger el cuerpo de la petición es un parámetro más, que se define entre la lista de parámetros de cada endpoint con la clave in: body para indicar que es el cuerpo de la petición. En OpenAPI v3 se indica por separado mediante la etiqueta requestBody. Se puede definir in situ o, si es reutilizable, en una subsección llamada requestBodies ubicada en otra nueva sección: components. Veremos ambas más adelante.
Responses/Content
En swagger se pueden indicar los mime-types o formatos que devuelve la API mediante los elementos consumes y produces. Esto puede hacerse a nivel de toda la API o a nivel de un endpoint particular, lo que sobreescribe la configuración global sólo para dicho endpoint.
En la versión 3 seguimos disponiendo de la sección responses para describir las respuestas, pero esta contiene una subsección denominada content en la cual podemos definir un esquema y un ejemplo distinto en función del mime-type a devolver. Ya no es necesaria la configuración de formatos a nivel de API, se hace siempre a nivel de endpoint. Es algo más tedioso, pero a la vez más flexible. Permite, al igual que en swagger, definir distintos ejemplos en función del mime-type, aunque la definición de ejemplos con formatos distintos a JSON sigue siendo tediosa.
Rangos de respuestas
Al igual que en swagger las respuestas se definen indicando el código de estado http que devuelven. Esto sigue siendo así, con el añadido de que se pueden indicar rangos de códigos de estado http. Por ejemplo, para errores no controlados es habitual usar default en swagger. En la versión 3 podemos indicar ‘5XX’ para referirnos a todos los códigos 500. Podemos hacer lo mismo para cualquier rango, ‘1XX’, ‘2XX’, etc. Es una opción más, pero hay que manejarla con cuidado por la dificultad de encajar distintas respuestas en el mismo esquema.
Servers
Dentro de un endpoint concreto es posible sobreescribir los servidores indicados en el elemento servers a nivel de API. Esta característica es útil para aunar bajo una misma API la funcionalidad de distintos servidores. No obstante, debe manejarse cuidadosamente. En la documentación generada este elemento se refleja en el tryout del endpoint.
Links
Este elemento se usa para enlazar todo o parte del resultado de una petición a un endpoint usándolo como parámetro para otra petición a otro distinto. Por ejemplo: supongamos que tenemos un POST que crea un usuario. La respuesta de dicha petición nos devolverá un identificador. Dicho identificador puede usarse para recuperar, modificar o eliminar el usuario que acabamos de crear, enlazándolo a los endpoints que definen dichas operaciones.
Components
Las sección definitions, parameters, responses y securityDefinitions desaparecen en la versión 3, siendo reemplazadas por una sección más genérica que contiene todas las secciones de v2 (definitions renombrada a schemas, por ejemplo) y algunas más.
Schemas
Sustituye a la sección definitions, siendo su funcionalidad la misma: definir los modelos de la API.
Parameters
Equivalente a la misma sección en la v2. La única diferencia es que los cuerpos de las peticiones y las cabeceras se definen en subsecciones específicas de components.
Responses
Tiene la misma funcionalidad que en la v2, solo que la definición de las respuestas debe ser acorde a la nueva forma de hacerlo, especificando un esquema por cada mime-type.

RequestBodies
En esta sección se definen los cuerpos de peticiones reutilizables. La definición es bastante distinta a la de un parámetro de entrada in: body de swagger. Se omite la etiqueta in (la sección de por sí indica por dónde entra el parámetro). El elemento name del parámetro se convierte en el identificador del cuerpo definido. El esquema del cuerpo se indica mediante la etiqueta content ligado a un mime-type concreto. Esto permite definir distintos cuerpos para distintos mime-types de entrada con el mismo modelo. Se ve mejor en la imagen de ejemplo.
Headers
Al igual que con los cuerpos de la petición, las cabeceras reutilizables se definen en esta sección. Las cabeceras en esta sección se definen como un parámetro omitiendo la etiqueta in y convirtiendo la etiqueta name en el nombre del modelo de cabecera como vemos en la imagen.
No obstante hay que indicar que las cabeceras definidas en esta sección sólo pueden usarse en las respuestas. Si necesitamos definir una cabecera de entrada lo haremos de la misma forma que en swagger, es decir, como parámetro.

Examples
Esta sección nos permite definir ejemplos reutilizables, lo cual resulta muy útil para no repetir ejemplos en las definiciones de las respuestas de cada endpoint. Siempre conviene personalizar los ejemplos, pero a veces se pueden reutilizar. También se puede usar la sección para mantener los ejemplos ordenados y localizables, simplificando la lectura de la definición de los endpoints.
Links
Aquí se pueden definir links reutilizables. Ya hemos hablado de ellos con anterioridad.
SecuritySchemes

Herramientas para trabajar con OpenAPI v3
La mayoría de las herramientas que vimos en el anterior tip es adecuada para trabajar con OpenAPI v3. Sin embargo algunos de los productos que hacen uso de definiciones OpenAPI no están preparados para la versión 3, o lo están sólo en sus versiones más modernas.
Hay que añadir, sin embargo, una nueva categoría de herramientas: los convertidores entre versiones. Existen convertidores online como Mermade swagger converter, que realiza la conversión de swagger a OpenAPI v3 subiendo el archivo de definición o mediante copy-paste en la propia interfaz.
También existe una potente herramienta de conversión online, APImatic Transformer, que convierte entre múltiples formatos. El inconveniente es que es de pago y sólo permite un número limitado de conversiones gratuitas por día, pero es una opción muy interesante por la cantidad de formatos soportados.
En este sentido también existe una utilidad en forma de paquete npm: api-spec-converter. Soporta varios formatos, aunque no tantos como Transformer. Se puede usar mediante línea de comandos, desde una aplicación node.js, o mediante un script embebido en el HTML de un frontal, lo que la hace bastante versátil.
Conclusiones
OpenAPI v3 soluciona parte de los problemas que planteaba swagger, aunque también plantea retos para los productos que usan definiciones de API estandarizadas a la hora de adaptarse.
La curva de aprendizaje de OpenAPI es algo más larga que la de swagger, especialmente si no se tiene experiencia previa con este, pero los resultados a la hora de definir son, en general, mejores.
En general se puede decir que OpenAPI v3 mejora a su predecesora, aunque aún le queda camino por recorrer.
Leave a comment
You must be logged in to post a comment.