¿Cansado/a de invertir tiempo codificando una especificación OpenApi? OpenApi Generator se encargará de ello para que solo te tengas que preocupar por el negocio y se eviten errores.

En primer lugar, empezaremos explicando las dos aproximaciones en el desarrollo de API’s Rest que podemos seguir: Code First Vs Api First o DesignFirst.

Code First

Consistiría en empezar a desarrollar la interfaz directamente y posteriormente podemos utilizar herramientas que nos generen la especificación del contrato, ya sea en swagger o en openapi (en el ecosistema spring son famosas las librerías de springfox y springdoc).

Esta aproximación hace un tiempo parecía más rápida (spoiler: más adelante vamos a ver que no). En su contra, podríamos decir que generalmente el desarrollador se pone directamente a trabajar sin estructurar un buen contrato y a veces sin consensuar con los equipos que vayan a trabajar con ese contrato… O, peor, si es la consumición podemos estar trabajando con ensayo y error hasta que nos ajustamos a la especificación (porque es más fácil cometer errores codificando que sí automáticamente lo generamos).

Además, otro tema muy importante es el de los bloqueos. Sin un contrato de referencia hasta que un equipo no termine su trabajo el resto de equipos que vayan a trabajar con ese contrato, estarán bloqueados o empezarán a trabajar y luego habrá otro trabajo de integración.

Api First

En este caso, lo primero es especificar el contrato antes de escribir la primera línea de código. Con esta aproximación surgen las siguientes ventajas.

En el fondo reducimos el tiempo de puesta en producción (time to market) al desacoplar los equipos de desarrollo. Incluso podemos tener un servidor que simule nuestro contrato (mock).

Además, como empezamos escribiendo el contrato es más fácil hacer cambios que si tenemos todo escrito y en producción. Asimismo, podemos detectar problemas de seguridad viendo el contrato escrito, la madurez de nuestro contrato, generar contract test…

Si no fuera poco, solo tenemos que mantener un fichero (que además podemos subir a un repositorio de código y tenerlo versionado). Sobre este tema, comentar que hay herramientas las cuales nos permiten gestionar este gobierno de las API y su ciclo de vida (un ejemplo sería apicurio). Además, no tendremos que añadir a nuestro proyecto librerías de terceros ni exponer ninguna url para tener la especificación (como con springfox o springdoc).

¿Vale y todo este rollo para qué?

Si has llegado hasta aquí es porque coincides conmigo en todas las ventajas de trabajar siguiendo la metodología de API first. Open Api Generator es una iniciativa de código abierto que lo que hace es facilitarnos el paso de la especificación a la implementación para que nosotros como desarrolladores ‘solo’ tengamos que preocuparnos de implementar la lógica de negocio y fallemos menos al implementar un contrato. Nos puede generar tanto la parte cliente como la parte servidora y todos los objetos especificados en el contrato. No solo ganamos velocidad en el desarrollo, sino que además no vamos a tener bugs. Además, puede generar código para los lenguajes de programación más usados (generadores).

Además, al tener el contrato escrito hay API Managers que nos pueden generar un servidor con respuestas que cumplen esta especificación y con el que poder integrar clientes. Hay productos que usando este enfoque nos ayudan a escribir más rápido nuestras especificaciones OpenApi, gobernarlas y mockearlas (un ejemplo sería stoplight). Incluso hay una proyecto en GitHub que nos permite levantar un docker que mockea nuestro contrato (mock server). Este punto para desacoplar y aliviar los típicos bloqueos puede ser una gran ayuda

Por ejemplo, si tuviéramos la especificación podríamos generar la implementación de un servicio y solo dedicarnos a escribir la lógica de negocio. Supongamos que queremos publicar el servicio sobre el recurso de hospitals. Generamos el código en una librería que podría quedar así (por una lado el modelo y por el otro el api):

Código en la librería, por una lado el modelo y por el otro el api.

Y luego solo tendríamos que implementar la interfaz y la lógica de negocio (con sus test por supuesto) y tendríamos un nuevo servicio desarrollado que se ajusta a una especificación en un time to market más reducido (otro ejemplo con el recurso de productos).

Implementamos la interfaz y la lógica de negocio y tendríamos un nuevo servicio desarrollado.

¿Cómo puedo usarlo?

En primer lugar, tiene una CLI escrita en node y multiplataforma que permite la generación a través de una simple interfaz a través de línea de comandos. También existe una imagen docker, un archivo jar e incluso un script bash.

Pero para mí, uno de los puntos más fuertes son sus plugins (maven y gradle). Esto hace que sea muy fácil su inclusión en la fase de construcción de nuestros proyectos o generar una pipeline genérica cuyo propósito sea la generación de la parte de servidora y cliente a partir de una especificación.

En el ejemplo estamos generando la parte servidora de una especificación swagger y el generador de spring-boot.

Generamos la parte servidora de una especificación swagger y el generador de spring-boot.

Llegados a este punto voy a comentar algunas personalizaciones que me han parecido bastante interesantes tener en cuenta (resto de configuraciones).

<additionalModelTypeAnnotations>@lombok.Builder;@lombok.NoArgsConstructor;@lombok.AllArgsConstructor;@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NOT_NULL})</additionalModelTypeAnnotations>

En cuanto a la parte cliente, si también usamos un ecosistema Java con Spring quedaría así. Importante comentar que la librería es webclient porque RestTemplate ha quedado deprecada.

En cuanto a la parte cliente, si también usamos un ecosistema Java con Spring quedaría así.

Otras personalizaciones que se pueden hacer son a partir de modificar las templates (mustache) que tienen por defecto. Con respecto a este punto se puede especificar al plugin la ruta de donde coger estas plantillas personalizadas. Por ejemplo, hacer que el modelo que se genera no permite modificaciones. Otra fue añadir una cabecera para permitir versionado basado en headers. Ejemplo de código (api.mustache):

{{/useRequestMappingOnInterface}}
public interface {{classname}} {
    final String HEADER_VERSION = "{{{vendorExtensions.x-version-header}}}";
{{#jdk8-default-interface}}
…
    @RequestMapping(
        method = RequestMethod.{{httpMethod}},
        value = "{{{path}}}"{{#singleContentTypes}}{{#hasProduces}},
        produces = "{{{vendorExtensions.x-accepts}}}"{{/hasProduces}}{{#hasConsumes}},
        consumes = "{{{vendorExtensions.x-content-type}}}"{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}},
        produces = { {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }{{/hasProduces}}{{#hasConsumes}},
        consumes = { {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }{{/hasConsumes}}{{/singleContentTypes}}{{#vendorExtensions.x-is-version-header}},
        headers = {"Api-Version=" + HEADER_VERSION } {{/vendorExtensions.x-is-version-header}}
    )

¿Y ahora qué?

Nos dedicaremos a programar el negocio que tienen estos contratos. Hemos desacoplado el método de desarrollo y además agilizado su implementación. En el caso del servidor bastaría con implementar la interfaz que se nos ha generado y en el caso de un cliente bastaría con configurar el endpoint al que atacamos.

Conclusiones

Open Api Generator tiene mucha potencia y su uso es bastante inmediato. Si es cierto que tiene muchos parámetros de configuración con los que podemos ajustar a lo que deseamos, pero nos va a exigir bucear en su documentación.

Por otro lado, como toda herramienta open source tiene algunos bugs que se van solucionando poco a poco y generando nuevas versiones. No obstante, para la mayoría de contratos que generamos cumple de sobra.

En mi experiencia he conseguido ahorrar bastante tiempo de desarrollo, ser fuente de soluciones y de desarrollos de calidad.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete