En el mundo dinámico de los microservicios, cualquier cosa puede cambiar: cualquier componente puede reescribirse en otro idioma utilizando diferentes marcos y arquitectura. Solo los contratos deben permanecer sin cambios, de modo que sea posible interactuar con el microservicio desde el exterior de manera constante, independientemente de las metamorfosis internas. Y hoy hablaremos sobre nuestro problema de elegir un formato para describir los contratos y compartir los artefactos encontrados.

La publicación fue preparada por
Anna Melekhova y
Vladimir Lapatin.Microservicios Al desarrollar Acronis Cyber Cloud, nos dimos cuenta de que no podíamos escapar de ellos. Y diseñar un microservicio es imposible sin formalizar un contrato, que es la interfaz de un microservicio.
Pero cuando un producto contiene más de un componente y el desarrollo de un contrato se convierte en una actividad regular, involuntariamente comienza a pensar en optimizar el proceso. Resulta obvio que la interfaz (contrato) y la implementación (microservicio) deben corresponder entre sí, que los diferentes componentes deben hacer lo mismo y que, sin una adopción centralizada de todas estas decisiones, cada equipo se verá obligado a dedicar tiempo a obtenerlas una y otra vez. .
Diseño de microservicio de Amazon del tuit de Werner Vogelis, CTO de Amazon¿Cuál es el dilema? De hecho, hay dos formas en que los microservicios interactúan: HTTP Rest y gRPC de Google. No queriendo participar en la pila de tecnología de Google, elegimos HTTP Rest. Las anotaciones a los contratos REST de HTTP se describen con mayor frecuencia en uno de dos formatos: RAML y OAS, anteriormente conocido como Swagger. Por lo tanto, cada equipo de desarrollo se enfrenta a la necesidad de elegir uno de los estándares. Pero, como resultó, hacer esta elección puede ser muy difícil.
¿Por qué anotaciones?
Se necesita una anotación para que un usuario externo pueda descubrir fácilmente qué se puede hacer con su servicio a través de su interfaz HTTP. Es decir, en un nivel básico, la anotación debe contener al menos una lista de recursos disponibles, sus métodos HTTP, cuerpos de solicitud, una enumeración de parámetros, una indicación de los encabezados necesarios y admitidos, así como códigos de retorno y formatos de respuesta. Un elemento extremadamente importante de la anotación del contrato es su descripción verbal ("¿qué sucede si agrega este parámetro de consulta a la solicitud?", "¿En qué caso volverá el código 400?")
Sin embargo, cuando se trata de desarrollar una gran cantidad de microservicios, quiero obtener un beneficio adicional de las anotaciones escritas. Por ejemplo, basado en RAML / Swagger, puede generar código de cliente y servidor en una gran cantidad de lenguajes de programación. También puede recibir automáticamente documentación para el microservicio y subirla a su portal de desarrollador :).
Un ejemplo de una descripción estructurada del contrato.Menos común es la práctica de probar microservicios basados en descripciones de contratos. Si escribió una anotación y un componente, puede crear una prueba automática que verifique la adecuación del servicio con varios tipos de datos de entrada. ¿El servicio devuelve un código de respuesta que no se describe en la anotación? ¿Podrá procesar correctamente los datos incorrectos a sabiendas?
Además, la implementación de alta calidad no solo de los contratos en sí, sino también de las herramientas para visualizar anotaciones hace que sea más fácil trabajar con el microservicio. Es decir, si el arquitecto describió cualitativamente el contrato, sobre la base de que los diseñadores y desarrolladores implementarán el servicio en otros productos sin costos de tiempo adicionales.
Para el funcionamiento de herramientas adicionales, tanto RAML como OAS tienen la capacidad de agregar metadatos que no son provistos por el estándar (
por ejemplo, esto se hace en OAS ).
En general, el campo de la creatividad en la aplicación de contratos para microservicios es enorme ... al menos teóricamente
Comparación de un erizo con una serpiente
Actualmente, el área de desarrollo prioritaria de Acronis es el desarrollo de Acronis Cyber Platform. Acronis Cyber Platform: estos son nuevos puntos de integración de servicios de terceros con Acronis Cyber Cloud y la parte de agente. Aunque nuestras API internas descritas en RAML estaban bien con nosotros, la necesidad de publicar la API nuevamente planteó la cuestión de elección: ¿qué estándar de anotación es mejor usar para nuestro trabajo?
Inicialmente, parecía que había dos soluciones: estos eran los desarrollos más comunes de RAML y Swagger (u OAS). Pero, de hecho, resultó que las alternativas no son al menos 2, sino 3 o más.
Por un lado, está RAML, un lenguaje poderoso y efectivo. Implementa bien la jerarquía y la herencia, por lo que este formato es más adecuado para las grandes empresas que necesitan muchas descripciones, es decir, no un producto, sino muchos microservicios que tienen partes comunes de contratos: esquemas de autenticación, los mismos tipos de datos, cuerpos de error.
Pero el desarrollador de RAML, Mulesoft, se ha unido al consorcio Open API que está desarrollando
Swagger . Por lo tanto, RAML suspendió su desarrollo. Para imaginar el formato del evento, imagine que los encargados de los principales componentes de Linux se pusieron a trabajar en Microsoft. Esta situación crea los requisitos previos para usar Swagger, que se está desarrollando dinámicamente y en la última tercera versión prácticamente se pone al día con RAML en términos de flexibilidad y funcionalidad.
Si no fuera por uno pero ...
Al final resultó que, no todas las utilidades de código abierto se han actualizado a la versión OAS 3.0. Para los microservicios en Go, lo más crítico será la falta de adaptación de
go-swagger a la última versión del estándar. Sin embargo, la diferencia entre Swagger 2 y Swagger 3 es
enorme . Por ejemplo, en la tercera versión, los desarrolladores:
- descripción mejorada de esquemas de autenticación
- soporte completo para el esquema JSON
- impulsó la capacidad de agregar ejemplos
La situación es divertida: al elegir un estándar, debe considerar RAML, Swagger 2 y Swagger 3 como alternativas separadas. Sin embargo, solo Swagger 2 tiene un buen soporte para el kit de herramientas OpenSource. RAML es muy flexible ... y complejo, y Swagger 3 no cuenta con el apoyo de la comunidad, por lo que debe utilizar herramientas patentadas o soluciones comerciales, que generalmente son muy caras.
Al mismo tiempo, si hay muchas características agradables en Swagger, como el portal ya preparado
editor.swagger.io , en el que puede descargar la anotación y obtener su visualización con una descripción detallada, enlaces y enlaces, entonces no existe la posibilidad de una RAML más fundamental y menos amigable. Sí, puede buscar algo entre los proyectos en GitHub, encontrar un análogo allí e implementarlo usted mismo. Sin embargo, en cualquier caso, alguien tendrá que apoyar el portal, que no es tan conveniente para el uso básico o las necesidades de prueba. Además, swagger es más "sin principios", bueno o liberal: se puede generar a partir de comentarios en el código, que, por supuesto, es contrario al principio de API primero y no es compatible con ninguna de las utilidades RAML,
En un momento, comenzamos a trabajar con RAML como un lenguaje más flexible y, como resultado, tuvimos que hacer mucho con nuestras propias manos. Por ejemplo, uno de los proyectos usa la utilidad de
ramlfication en pruebas unitarias, que solo admite RAML 0.8. Así que tuve que agregar muletas para que la utilidad pudiera "comer" RAML versión 1.0.
¿Necesito elegir?
Al habernos involucrado en agregar un ecosistema de soluciones para RAML, llegamos a la conclusión de que necesitamos convertir RAML a Swagger 2 y ya llevar a cabo toda la automatización, verificación, prueba y posterior optimización en él. Esta es una buena manera de aprovechar la flexibilidad de RAML y el soporte de herramientas comunitarias de Swagger.
Para resolver este problema, hay dos herramientas OpenSource que deberían garantizar la conversión de contratos:
- oas-raml-converter ahora es una utilidad no compatible. En el proceso de trabajar con ella, descubrimos que tiene una serie de problemas con RAML complejas que se "extienden" en una gran cantidad de archivos. Este programa está escrito en JavaScript y realiza un recorrido recursivo del árbol de sintaxis. Debido a la escritura dinámica, se hace difícil entender este código, por lo que decidimos no perder el tiempo escribiendo parches para una utilidad moribunda.
- webapi-parser es una herramienta de la misma compañía, que afirma estar lista para convertir todo y todo, y en cualquier dirección. Hasta la fecha, se ha anunciado la compatibilidad con RAML 0.8, RAML 1.0 y Swagger 2.0. Sin embargo, en el momento de nuestro estudio, la utilidad era EXTREMADAMENTE cruda e inutilizable. Los desarrolladores crean un tipo de IR , que les permitirá agregar rápidamente nuevos estándares en el futuro. Pero por ahora, todo esto simplemente no funciona.
Y estas no son todas las dificultades que hemos encontrado. Uno de los pasos en nuestra tubería es verificar que la RAML del repositorio sea correcta con respecto a la especificación. Probamos varias utilidades. Sorprendentemente, todos maldecían por nuestras anotaciones en diferentes lugares y con malas palabras completamente diferentes. Y no siempre es el caso :).
Al final, nos decidimos por el proyecto ahora obsoleto, que también tiene una serie de problemas (a veces se cae de la nada, tiene problemas al trabajar con expresiones regulares). Por lo tanto, no encontramos una manera de resolver las tareas de validación y conversión basadas en herramientas gratuitas, y decidimos usar una utilidad comercial. En el futuro, cuando las herramientas OpenSource se desarrollen más, resolver este problema puede ser más fácil. Mientras tanto, el tiempo y el trabajo involucrados en el "acabado" nos parecieron más significativos que el costo de un servicio comercial.
Conclusión
Después de todo esto, queríamos compartir nuestra experiencia y tener en cuenta que antes de elegir una herramienta para describir los contratos, debe determinar claramente qué quiere de él y qué presupuesto está dispuesto a invertir. Si se olvida de OpenSource, ahora hay una gran cantidad de servicios y productos que lo ayudarán a verificar, convertir y validar. Pero son caros, y a veces muy caros. Para una empresa grande, tales costos son tolerables, pero para una startup, puede convertirse en una gran carga.
Defina un conjunto de herramientas que usará más adelante. Por ejemplo, si solo necesita mostrar el contrato, será más fácil usar Swagger 2, que tiene una API hermosa, porque en RAML debe levantar y mantener el servicio usted mismo.
Cuantas más tareas tenga, mayor será la necesidad de herramientas, y serán diferentes para diferentes plataformas, y es mejor familiarizarse inmediatamente con las versiones disponibles para tomar una decisión que minimice sus costos en el futuro.
Pero vale la pena reconocer que todos los ecosistemas que existen hoy en día son imperfectos. Por lo tanto, si la compañía tiene fanáticos a los que les gusta trabajar en RAML, porque "le permite expresar sus pensamientos de manera más flexible", o, por el contrario, prefiere Swagger, porque "es más comprensible", es mejor dejarlos trabajar en lo que ellos desean. están acostumbrados y quieren hacerlo, porque el conjunto de herramientas de cualquiera de los formatos debe finalizarse con un archivo.
En cuanto a nuestra experiencia, en las siguientes publicaciones hablaremos sobre qué tipo de comprobaciones estáticas y dinámicas llevamos a cabo en función de nuestra arquitectura RAML-Swagger, así como qué documentación generamos de los contratos y cómo funciona todo.