En una
publicación anterior
, hablamos sobre cómo y por qué nosotros en Ancronis hacemos anotaciones para microservicios, y prometimos compartir nuestra práctica de usar un único formato API para toda la Plataforma Acronis Cyber. Hoy hablaremos de nuestra experiencia en las comprobaciones de anotaciones estáticas, también conocido como el primer paso en el camino para introducir anotaciones en una empresa.

Entonces, suponga que ya tiene anotaciones para todas o la mayoría de las API. Una pregunta razonable que nuestros colegas también nos hicieron: "¿Qué se puede hacer con estos objetos mágicos?"
De hecho, hay dos tipos de comprobaciones que se pueden hacer directamente por anotación. Las verificaciones estáticas van directamente a los textos de las anotaciones Swagger o RAML. No necesitan nada más, y pueden considerarse legítimamente la primera ventaja de usar contratos de microservicio formalizados.
Las comprobaciones dinámicas solo se pueden iniciar si tiene un servicio en funcionamiento. Son algo más complicados, ya que le permiten profundizar y verificar cuán válida es la anotación, probar la estabilidad del servicio y hacer mucho más. Pero este es el tema de la próxima publicación, y hoy nos centraremos en la estática.
¡Viva la guía API!
Para no confundirte a ti mismo ni a los demás, vale la pena mencionar de inmediato que las verificaciones de anotaciones estáticas se crean para controlar la conformidad de las anotaciones API (y, con suerte, las API mismas) con los requisitos corporativos. Pueden ser solo prácticas adoptadas por la empresa o una API de pautas completa, que formaliza las reglas para preparar la API para sus servicios.

Cuando hablamos del colorido mundo de los microservicios, esto es muy importante, porque cada equipo puede tener su propio marco, su propio lenguaje de programación, una pila única o algunas bibliotecas especiales. Bajo la influencia de prácticas específicas del microservicio, la presentación de la API para un observador externo está cambiando. Esto crea una variedad innecesaria. Para una interacción efectiva de los elementos de un ecosistema (o plataforma), es necesario "alinear" la API tanto como sea posible.
Aquí hay un ejemplo: el código 404 se devuelve a la API de un componente solo si el recurso no existe. Y el otro equipo vincula este error a la lógica de la aplicación y la API devolverá 404 cuando el usuario quiera comprar un producto que haya finalizado en el almacén.
Atygaev describió estos problemas muy claramente
aquí . Esta inconsistencia en la comprensión del código 404 ralentizará el desarrollo y conducirá a errores, lo que significa llamadas innecesarias de soporte u horas adicionales de depuración, pero en cualquier caso, problemas medidos en términos monetarios.
Los detalles de la sintaxis y los nombres adoptados por la compañía se complementan con varios aspectos específicos de REST. El desarrollador debe responder preguntas como:
- ¿POST será idempotente o no?
- ¿Qué códigos de error utilizamos y qué significan?
- ¿Puedo agregar lógica empresarial a los códigos de error?
Ahora imagine que cada equipo debe resolver individualmente estas respuestas.
El formato de la consulta de búsqueda también puede ser completamente diferente. Por ejemplo, hay alrededor de una docena de formas de crear una muestra en la que solo se enumerarán aquellos usuarios que tienen MacBookPro y ataques de virus frecuentes. Cuando se trabaja en un proyecto grande que consta de docenas de microservicios, es necesario que la sintaxis de la consulta de búsqueda sea común a todas las versiones y productos de la empresa. Y si una persona está acostumbrada a referirse a uno de los productos / servicios de su desarrollo, espera encontrar la misma estructura de solicitud y respuesta en otra. De lo contrario, no se evitará el asombro (y el dolor).
Muchas compañías, especialmente gigantes, como
Microsoft ,
PayPal ,
Google , tienen sus propias pautas y están muy bien pensadas. Pero usar las pautas de otras personas no siempre es posible, ya que están en gran medida vinculadas a los detalles de la empresa. Además, el pensamiento de todos tiene una estructura diferente, y las reglas pueden diferir simplemente porque es más conveniente para las personas trabajar de esta manera y no de otra manera.
La comprensión de que Acronis necesita su propia directriz API no llegó de inmediato, sino con el creciente número de desarrolladores, microservicios y clientes e integraciones realmente externos. En algún momento, el equipo de arquitectos tuvo que establecer reglas uniformes para declarar la API, teniendo en cuenta tanto la experiencia de los gigantes de TI mencionados anteriormente como las prácticas de facto ya establecidas en los equipos de desarrollo.
Uno de los problemas con esta implementación tardía de la API Guideline son las API publicadas existentes que no cumplen con los requisitos, lo que a su vez conlleva costos adicionales para rediseñar las interfaces y mantener la compatibilidad con versiones anteriores. Por lo tanto, si su modelo de negocio implica una futura integración y publicación de la API, entonces debe pensar en reglas uniformes lo antes posible.

Por supuesto, la adopción de las API de la Guía no hizo que todas las API fueran constitutivas automáticamente. Cada API tenía que ser analizada, cada devlid tenía que entender los nuevos requisitos. Por lo tanto, realizamos la automatización de las comprobaciones de RAML con la API Guideline que desarrollamos.
Análisis estático
Primero debe decidir qué analizaremos estáticamente. No todos los puntos API de la Guía pueden formalizarse, por lo que primero debe resaltar un conjunto de reglas que se puedan entender fácilmente a partir de la anotación API.
En la primera versión, identificamos las siguientes reglas:
- Verifique las descripciones de la API. Como dijimos en nuestro artículo anterior, puede crear documentación hermosa basada en la anotación API. Esto significa que cada recurso, parámetro de consulta y respuesta debe tener una descripción que brinde toda la información necesaria a cualquier usuario de nuestra API. Parecería un poco, pero ¡qué fácil es mostrar a los desarrolladores que su anotación no es rica en descripciones!
- Comprobación de la presencia y corrección de ejemplos. Los lenguajes de anotación API también le permiten describir ejemplos. Por ejemplo, en respuesta podemos agregar un ejemplo de una respuesta de servicio real, algo de la vida real. El uso de ejemplos indica cómo se debe usar y trabajar el punto final, y buscamos ejemplos a través del análisis estático de anotaciones.
- Validación de códigos de respuesta HTTP. El estándar HTTP define una gran cantidad de códigos, pero se pueden interpretar de diferentes maneras. Nuestra directriz formaliza el uso de códigos. También limitamos la aplicabilidad de diferentes códigos según el método HTTP. Por ejemplo, el código 201, de acuerdo con la especificación HTTP, se devuelve cuando se crea un recurso. Por lo tanto, GET que devuelve 201 será una llamada de atención (o el código se usa incorrectamente o GET crea el recurso). Por lo tanto, nuestra directriz API prohíbe dicho uso. Además, los arquitectos tienen conjuntos de códigos fijos para cada método, y ahora los verificamos en modo estático a nivel de anotaciones.
- Comprobando los métodos HTTP. Todos saben que el protocolo HTTP tiene un conjunto de métodos estándar (GET, POST, PUT, etc.), y también hace posible el uso de métodos personalizados. Nuestra directriz API describe los métodos permitidos que están permitidos, pero no deseados (OPCIONES), así como completamente prohibidos (solo se pueden usar con la bendición de los arquitectos). Prohibido incluir el método HEAD estándar, así como cualquier método personalizado. Todo esto también es fácil de verificar en las anotaciones a los contratos.
- Verificación de derechos de acceso. Esperamos que en 2019 la necesidad de soporte de autorización no requiera explicaciones adicionales. La buena documentación debe incluir información sobre qué roles admite la API y qué métodos de API están disponibles para cada rol. Además de documentar información sobre el modelo a seguir, grabada en el nivel de anotación, le permite hacer cosas mucho más interesantes en dinámica, sin embargo, hablaremos de esto en el próximo artículo.
- Validación de nombres. Alivia el dolor de cabeza por usar diferentes enfoques para nombrar entidades. En general, hay dos "campamentos": partidarios de CamelCase y snake_case.Camelcase, cuando cada palabra comienza con una letra mayúscula, y snake_case, cuando las palabras están separadas por guiones bajos y todo está escrito en minúsculas. En diferentes idiomas, se acostumbra dar nombres de diferentes maneras. Por ejemplo, snake_case se acepta en Python y CamelCase se adopta en Go o Java. Hicimos nuestra propia elección universal para todos los proyectos y corregimos en la Guía API. Por lo tanto, a través de anotaciones, verificamos los nombres de los recursos y parámetros de forma estática;
- Validación de encabezados personalizados. Este es otro ejemplo de una verificación de nombres, pero está vinculada específicamente a las cabezas. En Acronis, es habitual utilizar el formato del formulario X-Custom-Header-Name (a pesar de que este formato está en desuso). Y controlamos su cumplimiento a nivel de anotaciones.
- Verifique el soporte HTTPS. Cualquier servicio moderno debería ser compatible con HTTPS, y algunos creen que trabajar con HTTP en estos días generalmente es una mala noticia. Por lo tanto, se debe indicar la anotación RAML o Swagger. que el microservicio admite HTTPS sin HTTP.
- Verifique la estructura del URI. En tiempos prehistóricos, es decir, antes del lanzamiento de la API de guía, el URI de solicitud se veía diferente en diferentes servicios: en algún lugar / api / 2, en algún lugar / api / nombre_servicio / v2, y así sucesivamente. Ahora, en nuestra guía, se define una estructura de URI estándar para todas nuestras API. El manual describe cómo deben verse para no crear confusión.
- Comprobación de la compatibilidad de nuevas versiones. Otro factor que cualquier autor de API debe tener en cuenta es la compatibilidad con versiones anteriores. Es importante verificar si el código basado en la API anterior puede funcionar con la nueva versión. En función de este cambio se puede dividir en dos categorías: romper la compatibilidad con versiones anteriores y compatible. Todo el mundo sabe que los cambios de última hora son inaceptables, y si desea "mejorar" algo dramáticamente, el desarrollador debe lanzar una nueva versión de la API. Pero todos pueden cometer errores, por lo que nuestro otro objetivo en la etapa de comprobaciones estáticas es omitir solo los cambios compatibles y jurar los incompatibles. Se supone que la anotación, como el código, se almacena en el repositorio y, por lo tanto, tiene todo el historial de cambios. Por lo tanto, podemos verificar nuestra REST HTTP para compatibilidad con versiones anteriores. Por ejemplo, la adición de compatibilidad (método, parámetro, código de respuesta) no viola, y la eliminación puede causar pérdida de compatibilidad. Y esto ya puede verificarse a nivel de anotación.

Cuando no hay descripciones

Cuando hay descripciones
Conclusiones
Se necesita un análisis estático de las anotaciones para verificar (no, no la calidad del servicio), sino la calidad de la API. Esta etapa le permite alinear las interfaces del programa entre sí para que las personas trabajen en un entorno claro y comprensible donde todo sea bastante predecible.
Por supuesto, solo es necesario tratar con tal formalismo en compañías lo suficientemente grandes, cuando verificar todas las correspondencias "manualmente" es muy largo, costoso y poco confiable. Una pequeña empresa simplemente no la necesita. Al menos por el momento. Pero si en el futuro hay planes para convertirte en un unicornio, como Akronis, entonces las comprobaciones estáticas y la API Guideline te ayudarán.