La especificación AsyncAPI está en el foco en el mundo de la integración de software, ya que permite especificar APIs orientadas a eventos de manera estandarizada. En este artículo de explica el concepto de Event Driven Architecture (EDA), se describe la especificación AsyncAPI y se muestra un ejemplo de código.
AsyncAPI es una especificación liderada por Fran Méndez que permite definir APIs y que se enfoca en arquitecturas orientadas en eventos (EDA).
La OpenAPI Specification (anteriormente Swagger) es junto a RAML uno de los principales estándares utilizados para definir APIs. Aunque con OpenAPI 3.0 es posible describir callbacks – de tal manera que a la hora de invocar a una API se pueda especificar una URL a la que enviar la respuesta – las capacidades de OpenAPI para describir escenarios asíncronos orientados a eventos son bastante limitadas.
Una arquitectura orientada a eventos es un paradigma de diseño en el que una pieza de software (un consumidor de eventos) recibe una notificación de que un evento o mensaje ha sido publicado en un canal por otra pieza de software (un generador de eventos, o publicador).
A diferencia de un modelo clásico petición respuesta como el que caracteriza a las APIs RESTful tradicionales, en una EDA el generador de eventos no se queda bloqueado en espera a que el consumidor responda a su mensaje. Es un modelo mucho menos acoplado que el modelo petición / respuesta, ya que el publicador de eventos no conoce siquiera la identidad del consumidor de los eventos. En una EDA cobra mucha importancia el Canal, que normalmente suele ser un message bróker como RabbitMQ o Apache Kafka:
Las arquitecturas orientadas a eventos disfrutan de una alta escalabilidad y una mejor tolerancia a fallos. Así, ante una situación imprevista de elevada carga, una arquitectura tradicional basada en un modelo petición / respuesta suele bloquearse, ya que ante un componente saturado (una base de datos, un microservicio) los demás componentes que interactúan con dicha pieza de manera síncrona también se saturarán, produciendo problemas de escasez de hilos, timeouts, etc. Sin embargo, en una arquitectura orientada a eventos, los componentes con pobre rendimiento no bloquean a sus consumidores, sino que estos simplemente generan más eventos que son encolados, facilitando que se pueda reaccionar y mejorar el rendimiento de la solución sin rediseñarla, tan solo ampliando o escalando los recursos del sistema saturado.
El objetivo de la iniciativa AsyncAPI es conseguir que trabajar con EDA sea tan fácil como es hoy en día trabajar con APIs RESTful. Uno de los motivos del éxito de las APIs REST ha sido entre otros la existencia de estándares como OpenAPI que permiten editar especificaciones, generar documentación automáticamente, portales de desarrollo, generadores de código, generadores de mocks, etc.
Se trata de una especificación que es amigable tanto para máquinas como para humanos. Es agnóstica del protocolo, de tal manera que se puede utilizar para describir APIs que funcionan sobre diferentes protocolos como MQTT o WebSockets.
Estos son los principales elementos de la especificación:
Es posible definir esquemas de seguridad que se pueden utilizar para proteger operaciones. Algunos de los esquemas son: usuario y contraseña, API keys, certificados, flujos OAuth / OIDC, etc.
La especificación es extensible. Así, es posible añadir nuevas propiedades, las cuales deben llevar siempre el prefijo “x-“, como por ejemplo “x-internal-id”.
La mejor manera de entender AsyncAPI es viendo un ejemplo. Así, supongamos que necesitamos definir una API que describa un escenario asíncrono mediante el cual cada vez que un cliente nuevo hace una compra, un consumidor es avisado mediante un evento, de tal manera que este puede realizar algún tipo de acción. Podemos utilizar el editor online de AsyncAPI para teclear este código:
asyncapi: '2.0.0'
info:
title: Customer API
version: '1.0.0'
description: |
The Customer API sends an async message
when a new customer makes a purchase.
license:
name: Apache 2.0
url: 'https://www.apache.org/licenses/LICENSE-2.0'
servers:
example:
url: mqtt://example.org
protocol: mqtt
channels:
customers:
publish:
summary: Notifies a new customer has done a purchase.
operationId: onNewCustomer
message:
payload:
type: object
properties:
id:
type: integer
minimum: 0
description: Id of the new customer.
purchaseAmount:
type: integer
minimum: 0
description: Amount of the purchase.
name:
type: string
description: Name of the new customer.
Vemos a continuación cuales son las principales secciones del código:
Hemos visto cuales son las principales características de las arquitecturas orientadas a eventos y como la especificación AsyncAPI permite definir APIs asíncronas de una manera agnóstica al protocolo, documentando las propiedades de los mensajes intercambiados.