OpenAPI v2

· Swagger ·

Odoo image and text block

1. Introducción

Breve introducción a un lenguaje de definición de APIs REST y el conjunto de herramientas disponibles para manejarlo.

Debido al auge de las APIs y las arquitecturas de microservicios experimentado en los últimos años también se ha producido un auge en las herramientas de definición, así como su estandarización.

OpenAPI es la principal de ellas, siendo actualmente el estándar de facto de la industria. No es la única, recordemos que existe RAML, pero es la más utilizada actualmente. Está disponible en las versiones 2 y 3, siendo la primera de ellas la más extendida hasta el momento. 

2. Principios de definición de APIs REST

Para que una API REST esté correctamente definida es necesario respetar una serie de buenas prácticas, de las cuales sólo vemos unas pinceladas.


Autoconsumible

Una buena definición de API es autoconsumible. Esto significa que en la misma se contiene toda la información necesaria para consumir la API por completo en el mismo momento en que lees la definición. Es importante aportar descripciones y ejemplos de todos los elementos de la API, especialmente de los parámetros de entrada y de las salidas que producirá.

REST pragmático

Se debe intentar respetar en la medida de lo posible la arquitectura RESTFUL, pero no debemos caer en la tentación de convertirnos en talibanes del RESTFUL. A veces es necesario hacer excepciones, hasta cierto punto, si el cliente o la organización lo requieren. Se trata de que la arquitectura sea útil al cliente, no que el  cliente sea esclavo de la arquitectura. No obstante hay que incidir en que se respete el correcto uso de los métodos HTTP, los códigos de estado, las cabeceras, los formatos de E/S, etc.

Formatos de entrada / salida

Respecto a los formatos siempre se debe recomendar JSON, aunque no se deben excluir tajantemente otros estándares ampliamente utilizados en la industria, como XML. 

Lo que sí debe evitarse es mezclar distintos formatos en una misma API, salvo que la naturaleza del recurso lo requiera. Por ejemplo, todos los endpoints de una API devuelven JSON, excepto uno que devuelve documentos PDF. Si es necesario devolver PDF se debe hacer. Lo que no se debe hacer es mezclar JSON, XML  texto plano sin ningún tipo de organización o motivo justificado.

Los parámetros numéricos deben definirse preferiblemente como tales, no como cadenas de texto. Las fechas deben respetar un estándar, siendo ISO 8601 el recomendado.


Respuesta estándar

Es muy recomendable que las APIs tengan una respuesta homogénea para todos los recursos que exponen. Evidentemente los datos quedan excluidos, ya que cada uno tiene su propia naturaleza, pero se deben devolver encapsulados en una respuesta que contenga información general sobre el resultado de la petición.

Un ejemplo de respuesta estándar podría ser este:

{
 "result": {
    "status": boolean, 
    "http_code": integer,
    "info": "string",
    "errors": [
      {
        "code": integer,
        "message": "string"
      }
    ]
  },
  "data":{...}
}

URLs sencillas y recursos claros

Debemos evitar las URLs interminables en la definición. Otra cosa es que un identificador de recurso sea más largo que la propia URL, pero en principio nuestras URLs no deberían tener más de tres niveles, aunque no es imperativo (recordad que no somos talibanes). Por ejemplo:

  ·  GET /clientes/{id}/cuentas.

También debemos procurar que los nombres de los recursos sean descriptivos de lo que devuelven. Se deben evitar nombres genéricos como resources, items, objects, etc. En el ejemplo anterior queda claro que se devuelven las cuentas de un cliente en concreto. A este respecto cabe destacar que se deben indicar correctamente las relaciones entre elementos. La estructura de la URL debe respetar el patrón /recurso/{identificador}/subrecurso/{identificador}

¿Verbos? Sólo HTTP, gracias

Debemos evitar que los recursos contengan verbos. Para eso ya están los métodos HTTP (GET , POST, etc). Si añadimos verbos lo único que hacemos es introducir información redundante y alargar las URLs innecesariamente. Los recursos deben ser sustantivos en plural. Por poner un ejemplo, ¿cuál de estos recursos expresa mejor la información que expone?

  ·  GET /clientes/{id}/cuentas
  ·  GET /clientes/cuentas/getAccountByCustomerId

Y encima el verbo está en inglés…

Un ejemplo REAL de recurso en una API de un cliente:

"GET /cfrcie9subclase2/search/findByFcBajaFilaIsNullAndId_cdcie9ClaseAndId_cdcie9SubclaseOrderByDsCie9Subclase2"

Da escalofríos sólo de verlo.


3. Documento de definición

Se ha hecho común hablar del swagger de la API para referirnos al documento de definición. Sin embargo, un documento de definición de API puede escribirse en RAML, en una hoja excel, en un documento word escrito en inglés o en una tablilla de cera en swahili. Es el documento en el que se define por completo una API, respetando por supuesto las buenas prácticas expuestas anteriormente. Se puede hacer de muchas formas, pero la ventaja que nos ofrece OpenAPI v2 (y v3 también) es que es un lenguaje estandarizado, fuertemente estructurado y, por tanto, susceptible de ser interpretado por herramientas de software. 

Este hecho nos da la idea de que, a partir de una definición escrita en OpenAPI, podemos usar todo tipo de herramientas para realizar distintas tareas:

  ·  Validar si la definición se ajusta al estándar OpenAPI
  ·  Generar documentación
  ·  Generar código
  ·  Generar suites de pruebas
  ·  ...

Odoo image and text block

Estructura del documento de definición con swagger

Para realizar una definición correcta de una API usando OpenAPI v2 debemos ceñirnos al mismo y respetar su estructura. Podemos escribirlo en YAML o JSON, pero los elementos son los mismos.


Vamos a hacer un breve repaso a dicha estructura:

  ·  swagger:
Siempre se comienza con esta etiqueta, con valor ‘2.0’. De esta forma indicamos que se trata de un documento escrito siguiendo el estándar OpenAPI v2.

  ·  info:
Este objeto contiene la siguiente información y otra no obligatoria pero no menos importante:

    - Title: nombre de la API
    - Version: versión de la API
    - Description: no es obligatoria, pero como se ha dicho anteriormente hay que describir todo, aunque pequemos de pesados. Mejor ser pesados a que nos estén llamando constantemente para saber para qué sirve y cómo se consume la API.

  ·  host:
Indica la máquina en la que se aloja la implementación de la API. Puede ser un nombre de dominio o una combinación máquina:puerto. Se debe excluir el protocolo, que viene indicado por otro elemento de OpenAPI.

  ·  basepath: 
Indica el contexto para construir la URL base de la API.

  ·  schemes:
Este es el elemento que indica el protocolo. Se trata de un array en el que podemos especificar HTTP, HTTPS o ambos. La URL base se compondrá como una combinación de este y los elementos anteriores: scheme + host + basepath.
Algún API manager (WSO2 AM) incluye también la versión en la URL base. 
Si se especifican ambos protocolos se construyen dos URLs, una para cada uno.

 

   ·  paths:
Esta es la sección que se usa para definir los endpoints, entendidos como recurso + método HTTP. Se debe definir todo:

    - Ruta
    - 
Descripción
    - 
Parámetros de entrada (tipos, restricciones y ejemplos)
    - 
Respuestas posibles (todas, así como ejemplos para todas ellas)

No vamos a entrar en detalles porque requiere una explicación mucho más larga de la que cabe en este documento. Enlazaremos la documentación de OpenAPI v2 para aquellos que deseen ampliar su conocimiento.

  ·  definitions:
En esta sección podemos definir todos los modelos de objetos que vayamos a usar para entradas y salidas. Todo lo que definamos aquí es reutilizable. De igual forma que con la sección anterior remitimos a la documentación oficial de OpenAPI v2.

  ·  parameters:
Aquí se definen los parámetros reutilizables para toda la API. Si no se van a reutilizar es preferible definirlos en la sección paths sólo en el endpoint al que pertenecen

  ·  responses:
De igual forma que con los parámetros se pueden definir respuestas reutilizables comunes a varios o todos los endpoints en esta sección.

  ·  security:
En esta sección se define un array con los esquemas de autenticación soportados por la API. OpenAPI v2 soporta la definición de los esquemas Basic Authentication, API Key y cualquiera de los flujos Oauth2. Estos esquemas se pueden referenciar desde los endpoints en la sección paths.

  ·  securityDefinitions:
En esta sección se definen los detalles de los esquemas de autenticación definidos en la sección anterior (tipo, método de entrada, URLs de autenticación y petición de token, etc).

Odoo image and text block

4. Herramientas para definir APIs con swagger

Tenemos disponibles multitud de herramientas para realizar el documento de definición usando OpenAPI v2. La mayoría son gratuitas, pero las hay de pago. Algunos ejemplos:

  ·  Editor online: disponible en https://editor.swagger.io/ 
Permite editar y navegar por el documento. Presenta la definición en el lado izquierdo de la pantalla y la documentación generada en el lado derecho. A medida que se edita el documento la documentación cambia en caliente.

  ·  Swaggerhub: Es una suite de pago que, aparte del editor, ofrece otros servicios como la generación de mock servers a partir de la definición, dominios para almacenar definiciones de elementos comunes entre distintas APIs o validación de estilo para mantener una misma línea entre todas las APIs de una organización.

  ·  Visual Studio Code: Añadiendo tres plugins tenemos una herramienta bastante completa para editar,  validar y generar la documentación de una API.

  ·  IntelliJ Idea: Un conocido IDE Java que, con los plugins adecuados, ofrece la misma funcionalidad que VS Code.

  ·  Otras: APIary, Apitive studio, RepreZen ...

5. Utilidad para otros productos

Como se ha mencionado anteriormente, la estructura de OpenAPI posibilita que otras herramientas puedan leer, interpretar e incluso manipular una definición de API para generar valor para una organización.

Algunos ejemplos conocidos son los siguientes:

  • Publicación de la API en un API Gateway (WSO2)

  • Generación de código de cliente y de servidor (swagger codegen). En este aspecto cabe destacar la herramienta desarrollada en colaboración entre Cloudappi y Madrid Digital para generar el código de servidor a partir de una definición y una base de datos. Se genera un arquetipo en lenguaje Java con el framework Spring Boot.

  • Generación de documentación (Bump, openapi-viewer para VS Code)

  • Generación de test suites: Postman es capaz de generar automáticamente una suite de pruebas básica a partir de una definición OpenAPI. 

  • En Cloudappi hemos desarrollado swagger2postman, que es una herramienta de generación de pruebas más completa. También se ha realizado en colaboración con Madrid Digital.

  • Mock servers: swaggerhub, postman y otras herramientas son capaces de levantar un servidor con una implementación estática a partir de una definición OpenAPI.


Odoo text and image block

Blog realizado por David Marín

Si quieres saber más sobre AKA Swagger,

no dudes en contactar con nuestros expertos.

Escriba un comentario

Usted debe ser registrado escribir un comentario.