Sí, así que pasaré esto a Alex. Muy bien, muchas gracias, Alex y Lana. Si tienen preguntas, nuestros oradores están aquí. Pero por ahora, compartiré mi pantalla nuevamente y comenzaré la sesión.
Hola a todos. Mi nombre es Alex. Soy un gerente de ingeniería en
Shopify. Y hoy, estoy muy emocionado de hablar con ustedes sobre un desafío que enfrentamos a gran escala en
Shopify, la contextualización de las APIs de
GraphQL. Entonces, hoy, lo que voy a hablar primero es el contexto y el problema que estamos tratando de enfrentar, los cuatro enfoques diferentes que utilizamos para intentar resolver este problema y, en última instancia, el que elegimos, las directivas. Les hablaré sobre qué es una directiva, ejemplos de directivas personalizadas y predefinidas, y cómo podemos crear las nuestras propias. Antes de entrar en detalles, todas las buenas charlas de
GraphQL comienzan con una consulta. Les daré un poco de contexto sobre cómo llegamos aquí. En
Shopify, tenemos varias APIs y una de esas APIs se llama API Storefront. Es una API de
GraphQL que impulsa las tiendas personalizadas. Una de las consultas más básicas que harás cuando muestres una tienda es mostrar productos, como una camiseta, sus variantes, como el tamaño o el color de ese producto, y luego su precio, lo que el cliente pagará por él. Y esta es una consulta muy básica. Aquí estamos viendo eso y estamos devolviendo el producto, las variantes y el precio de $7.00 USD. Hasta ahora, no hay problemas. Pero, como con todas las grandes plataformas de software, nuestros requisitos están cambiando con el tiempo. Entonces,
Shopify introdujo la multi-moneda, donde los clientes pueden comprar productos en diferentes monedas según lo que deseen pagar. Hemos evolucionado nuestra API de
GraphQL para incluir un nuevo campo llamado precios de presentación. Aquí puedes ver que tenemos el producto, sus variantes y el campo de precios de presentación, que toma un argumento de monedas de presentación. Entonces, en este caso, estoy obteniendo los precios, pero para dólares australianos. Esto funciona como esperas. Devolvemos la respuesta que tiene la misma cantidad, pero convertida a dólares australianos. Esto es realmente útil si puedes imaginar una tienda personalizada que tiene un selector de moneda donde puedes seleccionar en qué moneda el cliente desea comprar. Nuevamente, es relativamente simple, por lo que aún no hemos tenido demasiados problemas.
Y, como puedes imaginar, nuestros requisitos cambian una vez más. Shopify introdujo una nueva función llamada fijación de precios internacionales. Bajo este modelo, ya no mostramos precios basados en una moneda, sino en la ubicación geográfica de la persona. Por ejemplo, podrías tener un cliente en Francia que paga 10 euros, pero un cliente en Italia que también paga en euros podría gastar 15 euros en el mismo producto. Y esto podría basarse en diferentes factores que el comerciante desea controlar, como el margen o cualquier tipo de centro de costos que necesiten tener en cuenta. Entonces, estamos comenzando a ver este problema en el que tenemos una API de GraphQL que al principio era simple, pero está introduciendo más y más requisitos, y nuestras experiencias se están volviendo más y más contextualizadas según la ubicación del comprador, lo que el comprador necesita ver, y así sucesivamente. Entonces, necesitábamos una API que admitiera esto. Un poco más de contexto aquí es que no era tan simple como que necesitábamos mostrar solo precios. Necesitábamos mostrar el precio, necesitábamos mostrar el precio de comparación, que es algo como el precio de venta sugerido, necesitábamos mostrar rangos de precios, cuáles son los precios mínimos y máximos para un producto y otros campos que necesitan tener en cuenta dónde se encuentra el comprador. También sabíamos que nos estábamos moviendo hacia un modelo donde, nuevamente, nuestras experiencias se están volviendo cada vez más contextualmente conscientes. Por ejemplo, queremos contextualizar una tienda según la ubicación minorista preferida del cliente para poder mostrar información, como cuánto está disponible en stock para que lo recojan en la tienda. Ahora tienes el problema de lo que necesitábamos resolver para una API de GraphQL más contextualizada basada en la experiencia del comprador. Voy a profundizar en los diferentes enfoques que utilizamos para intentar resolver este problema.
Entonces, primero tenemos los encabezados. Aquí estás viendo los encabezados que podríamos pasar para contextualizar la API. Sabíamos que ya estábamos pasando un encabezado de token de acceso para que los clientes de la API obtuvieran acceso a los campos que están solicitando, por lo que pensamos que podrían pasar otro encabezado con el país como argumento. Sería algo sencillo porque los clientes de la API ya están enviando estos encabezados y podríamos obtener ese valor y devolver la respuesta correcta en función de eso. Los aspectos positivos aquí son que todos los campos se resolverán al precio correcto del país con esa moneda, no hubo grandes cambios en el esquema de la API, por lo que los clientes existentes podrían adoptarlo. Pero, por otro lado, una de las razones por las que amamos tanto GraphQL es que es un sistema tipado. Por lo tanto, no hay forma de que podamos validar proactivamente que el código de país que se envía en el encabezado sea uno válido que admitamos. Tampoco admite nuestro sistema de versión y deprecación de la API. Introducimos APIs cada tres meses y no habría una forma sencilla para que los clientes de la API sepan si se introduce un nuevo contexto o si se elimina uno a medida que desarrollamos nuevas funciones. Por lo tanto, se vuelve muy difícil de manipular con el tiempo. Por esa razón, los encabezados no parecían ser la solución. El siguiente enfoque que tomamos fueron los argumentos. Esta es lo que yo diría que es la solución más simple que podría funcionar. Podríamos agregar un argumento de código de país a cada campo que lo necesite. Aquí puedes ver que estamos obteniendo el producto. Sus variantes nuevamente, pero en este caso tenemos un precio con un argumento de Francia, un precio de comparación con un argumento de Francia y un rango de precios con un argumento de Francia. Los aspectos positivos aquí son que es muy explícito. Definitivamente no hay confusión sobre qué campos devolverán qué valores. También nos beneficiamos de que esté en nuestra definición de esquema y tenga esas validaciones. Por lo tanto, sabemos que solo podemos enviar un argumento de código de país a estos campos. También tenemos el soporte de versión de la API que mencioné antes, podemos evolucionar esto con el tiempo a medida que introducimos nuevos argumentos o los eliminamos. Pero los aspectos negativos aquí son que abre la posibilidad de que los clientes de la API agreguen diferentes valores a diferentes campos. Realmente queríamos asegurarnos de que solo ofreciéramos una experiencia de cliente consistente y parece un poco incómodo que puedas mostrar el precio para Francia, pero un precio de comparación para Italia. Además, a medida que introducimos más campos y más contexto, como la compra en línea, recoger en la tienda, deberás agregar esos argumentos a cada campo que lo necesite. Aquí puedes ver el ejemplo de cómo eso podría no funcionar tan bien. Tienes el precio para Francia, un precio de comparación para Estados Unidos y un rango de precios para Italia.
Nuestra siguiente opción que consideramos fue el enfoque del espectador. Esto es algo que GitHub utiliza en su API de GraphQL para mostrar información de usuario autenticado. En este enfoque, tenemos un campo de nivel superior llamado espectador que toma un solo argumento de país para Francia y luego el resto de los campos se resuelven debajo de él para producto, variante y precios. Esto va en la dirección correcta. Ahora, cuando resolvemos esta respuesta, estamos devolviendo una experiencia consistente que tiene precios solo en euros, solo para Francia.
Comments