La característica final de mi DSL es el soporte para Apollo Federation, que permite a las organizaciones construir un grafo unificado distribuido en diferentes equipos. Este enfoque permite a los equipos exponer eficientemente una API de GraphQL sobre APIs preexistentes, componer sus APIs juntas y reducir el acoplamiento de tipos entre dominios y equipos. Además, el enfoque dirigido por directivas proporciona flexibilidad para combinar diferentes comportamientos agregando diferentes directivas en el mismo archivo. Aún queda trabajo por hacer, incluyendo el soporte para uniones de GraphQL, la traducción entre errores de gRPC y GraphQL, y la utilización de RPCs de transmisión de gRPC para suscripciones de datos en tiempo real. Estoy abierto a comentarios y sugerencias sobre casos de uso y características que no he abordado en el DSL hasta ahora.
En lugar de eso, la característica final de mi DSL de la que quiero hablar es el soporte para Apollo Federation. Veo que este enfoque dirigido por directivas funciona bien para las organizaciones que adoptan Apollo Federation para construir un grafo unificado distribuido en muchos equipos diferentes. Cada equipo que posee un dominio complejo único, ya sea pagos, inventario, calificaciones y reseñas, puede utilizar este enfoque para exponer eficientemente una API de GraphQL sobre cualquier API preexistente, simplemente escribiendo un archivo de esquema. Y luego, pueden componer sus APIs juntas para construir una única API de toda la empresa utilizando Federation. Las dos semánticas que quería soportar son la capacidad de devolver referencias a entidades y la capacidad de exponer entidades como puntos de entrada al grafo, lo que permite unir data en subgrafos. En este ejemplo, en lugar de resolver la relación para el tipo persona, con otra directiva fetch que realiza una llamada a una API propiedad de un equipo diferente, parte de una organización diferente, tal vez en una zona horaria diferente. En su lugar, puedo envolver la clave externa del director en este tipo muy pequeño que no hace modelar la relación, pero utilizando solo data que conozco en este dominio en particular. Si agrego las directivas de Federation e identifico este tipo como una entidad clave, Apollo Federation puede utilizar esta data para obtener data adicional para este tipo de otros subgrafos. Esta es una práctica útil en una organización distribuida, porque reduce el acoplamiento de tipos entre dominios y equipos. Apollo Federation maneja la composición de data en la capa de la API. En lugar de requerir que mi equipo construya una serie de solicitudes síncronas a los servicios de otro equipo, lo que vincularía el tiempo de actividad de mis servicios al de ellos. Y por último, decidí permitir agregar la directiva fetch directamente a los tipos, no solo a los campos. Esto es equivalente al gancho de resolución de referencia en Apollo Federation. Al proporcionar una entidad clave de esta manera, Apollo Federation puede unir data de este tipo con referencias y otra data de otros subgrafos.
Además de admitir la federación, creo que esto señala otro beneficio del enfoque dirigido por directivas, la capacidad de combinar diferentes comportamientos simplemente agregando diferentes directivas en el mismo archivo. Apollo tiene una directiva de control de caché incorporada que podríamos agregar fácilmente aquí. También estamos trabajando en directivas para el costo de operación, autorización y muchos otros comportamientos que funcionarían bien en el sistema. Definitivamente hay mucho más por hacer en mi prototipo antes de que esté listo para producción. Algunas de las cosas en mi lista de tareas pendientes incluyen el soporte para uniones de GraphQL, donde Protobuf tiene esta palabra clave `oneof` y no es exactamente lo mismo, pero estoy bastante seguro de que hay una forma de traducir entre ellos con el DSL. Los errores de gRPC y los errores de GraphQL en realidad tienen más en común de lo que podrías pensar, pero no he dedicado mucho tiempo a tratar de averiguar cómo traducir entre ellos tampoco. Creo que hay algunas ideas realmente poderosas en este enfoque, incluida la capacidad de utilizar RPCs de transmisión de gRPC para alimentar suscripciones de data en tiempo real, pero hay mucho trabajo que tengo que hacer para descubrir cómo hacerlo. Y estoy seguro de que me he perdido muchas cosas. Me encantaría saber qué casos de uso y características te gustaría que aborde en este DSL hasta ahora.
Para concluir, quiero volver a visitar los valores de los que hablé anteriormente y evaluar cada uno de los enfoques. Los dos enfoques tradicionales, basados en esquemas y basados en código, son excelentes. No desaparecerán pronto. Permiten mucha flexibilidad en el diseño del esquema y la capacidad de evolucionar tu API y vincularla a cualquier fuente de data en el fondo. Pero según mi criterio, fallan porque son realmente costosos. Escribir todos esos resolvedores es una gran inversión inicial y resulta en mucho código que debes mantener durante mucho tiempo.
Comments