Catálogo Swagger centralizado (microservicios)

A menudo, vemos muchos servicios con un extenso catálogo de OpenAPI que ayudan a la integración con las APIs que se están consumiendo. Muchos de estos servicios no siguen una arquitectura de microservicios y lo que básicamente hacen es exponer todos sus Endpoints desde el mismo paquete Java a través de la interfaz de Swagger incorporada en las propias dependencias de OpenAPI.

¿Qué ocurre cuando tenemos una gran cantidad de microservicios independientes y queremos un solo catálogo para todos? Es una pregunta que, una vez nos adentramos a buscar en distintos foros y blogs de información, vemos que no tiene una única respuesta y hay muchas soluciones posibles, cada cual más enrevesada. 

Es por ello que surge la necesidad de hacerlo de una forma más estandarizada, sin tener que recurrir a crear servicios propios codificando lo necesario para poder tener un catálogo que muestre todas las APIs que queremos en un solo punto. Y lo curioso es que es realmente sencillo, pero hay que tener ciertas cosas en cuenta que contaremos a continuación.

Requisitos

Es necesario tener en cuenta los siguientes requisitos antes de abordar el catálogo único:

  1. Se necesitan tener publicados los microservicios con la documentación de Swagger expuesta: habitualmente suelen estar publicados en la dirección: ${URL_SERVICIO}/v3/api-docs (si usas la versión 3), pero es cambiable por configuración.
  2. Es necesaria una correcta configuración de CORS: en los microservicios cuya documentación va a ser consumida, dado que en caso negativo la interfaz de swagger única no podrá recuperar la información necesaria para su correcto funcionamiento.
  3. Existe la posibilidad de usar imágenes públicas de Docker Hub: para poder consumir la de swagger-ui.

En nuestro local

Supongamos que tenemos dos servicios publicados en nuestro entorno local en los puertos 8080 y 8081, y que cumplimos los requisitos anteriores. Necesitaríamos configurar una imagen de Docker con las variables de entorno apropiadas, que en este caso es simplemente una: URLS.

docker-compose.yml

version: "3.3"
services:
  swagger-ui:
    image: swaggerapi/swagger-ui
    container_name: "swagger-ui"
    ports:
      - "8088:8080"
    environment:
      URLS: "[{name:'Service1',url:'http://localhost:8081/v3/api-docs'},{name:'Service2',url:'http://localhost:8082/v3/api-docs'},]"

Esta configuración publicaría en nuestro puerto 8088 (http://localhost:8088), que buscaría lo siguiente:

  • Service1 en la URL: http://localhost:8081/v3/api-docs
  • Service2 en la URL: http://localhost:8082/v3/api-docs

Siendo el nombre del servicio totalmente cambiable, no depende del real del microservicio.

Publicándolo en nuestro clúster

Visto lo simple que es hacer uso de swagger-ui a través de Docker, se espera que con una apropiada configuración en Kubernetes también será sencillo, como es el caso:

Deployment

kind: Deployment
apiVersion: apps/v1
metadata:
  name: services-swagger-ui
  namespace: services-namespace
  labels:
    app: services-swagger-ui
spec:
  replicas: 1
  selector:
    matchLabels:
      app: services-swagger-ui
  template:
    metadata:
      labels:
        app: services-swagger-ui
    spec:
      containers:
        - name: services-swagger-ui
          image: 'swaggerapi/swagger-ui:v4.10.3'
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          env:
            - name: URLS
              value: >-
                [{name:'Service1',url:'https://service1url.com/v3/api-docs'},{name:'Service2',url:'https://service2url.com/v3/api-docs'}]
          resources:
            limits:
              cpu: 50m
              memory: 50Mi
            requests:
              cpu: 5m
              memory: 5Mi
          imagePullPolicy: IfNotPresent
      restartPolicy: Always

En el anterior deployment, ajustándose a la versión v4.10.3 de la imagen pública, se estaría configurando las documentaciones que podemos encontrar en:

  • https://service1url.com/v3/api-docs
  • https://service2url.com/v3/api-docs

A nivel de recursos, como se puede observar la cantidad de memoria y CPU usada es bastante pequeña, y haciendo pruebas no se ha llegado ni a una décima parte de los límites asignados en este ejemplo.

Cabe destacar que la imagen de Docker es configurable por muchas variables de entorno que se pueden encontrar en su documentación. También existen variables de configuración de Nginx, que es el servidor a través del que se publica internamente el contenido de swagger-ui dentro de docker, que pueden observarse en su GitHub público. Cabe destacar por ejemplo la variable de entorno BASE_URL para configurar el path, siendo por defecto ‘/’.

Por supuesto, de cara a publicar el contenido de esta imagen al exterior haría falta las definiciones de los servicios de kubernetes necesarios para ello (service, ingress, load balancer,… etc), que ya son más concretos del entorno que se esté usando.

Imagen de cabecera: 2H Media en Unsplash

Autores

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *