Recreando la caché GraphQL de urql en el borde

Rate this content
Bookmark

Tabla de contenidos:
- Desplegando una API GraphQL predefinida
- Creando un worker en el borde + caché en Cloudflare
- Configurando la caché basada en los nombres de tipo
- Agregando invalidación basada en los tipos de retorno de mutación

114 min
13 Dec, 2021

Comments

Sign in or register to post your comment.

Video Summary and Transcription

El masterclass cubrió varios temas relacionados con el desarrollo y la ingeniería de software. Incluyó discusiones sobre codificación, comunicación y solución de problemas de configuración de Wrangler. Los participantes aprendieron sobre la proxyización de solicitudes en Cloudflare Workers, la identificación de mutaciones en consultas de GraphQL y el almacenamiento en caché de respuestas en un almacén KV. También exploraron el AST con astexplorer.net y manipularon el AST para agregar nombres de tipo a las consultas. El masterclass concluyó con una discusión sobre la caché de suscripciones en GraphQL y el manejo de mutaciones e invalidación de consultas.

Available in English

1. Introducción a la Codificación y Comunicación

Short description:

A continuación, vamos a concluir la sesión con Timo. ¿Puede empezar? ¿Puedes mostrarle cómo codificar un curso? Tyto, ¿puedes explicar el concepto del que estás hablando? Gran parte de mi contenido se centra en la comunicación. Me siento abrumado pero apasionado. Hemos recibido algunas solicitudes para obtener datos y realizar algunas validaciones. Si tienes un punto final gráfico básico, fantástico. Si no, utiliza el enlace proporcionado para crear uno. Podemos usar eso para el taller. Déjame enviarte un repositorio. Ahora, vamos a empezar. Instala las dependencias con NPMCI y Rangler. Inicia sesión con tu cuenta de CloudFlare. Ejecuta npm start y maneja el error de tipo. Comienza a hacer solicitudes GraphQL. Deberíamos verlas registradas en la consola. Proximemos la solicitud y maneja el error.

A continuación, vamos a concluir la sesión con Timo. ¿Puede empezar? Él está aquí contigo, ¿no es así Timo? ¿Puedes mostrarle cómo codificar un curso? Debe ser capaz de hacerlo. Así que vamos a seguir adelante y ponerlo en marcha. Tyto, ¿puedes explicar el concepto del que estás hablando? ¿Y puedes hablar sobre la comunicación y el design?

Sí, definitivamente. Gran parte de mi contenido en este momento se centra en la comunicación. Me siento un poco abrumado. No es que quiera admitirlo, pero estoy un poco abrumado porque me apasiona mucho la comunicación y hemos recibido algunas solicitudes para obtener data, pero también queremos hacer algunas invalidaciones. Así que si tienes un punto final básico, como un punto final gráfico, fantástico, si no, simplemente ve a este enlace en el chat. En este ejemplo, nos da un pequeño esquema JSON. Simplemente haz clic en `extend JSON`, despliega la API. Y luego obtenemos un pequeño enlace aquí y ahora podemos hacer algunas solicitudes graphQL. Así que si entro, si entro en Insomnia aquí y digo, obtener usuarios, por ejemplo, deberíamos ver, ahí vamos. Tenemos un montón de usuarios. Así que crea el tuyo propio, si todos tienen el suyo, verás que obtienes un pequeño URL único. Guárdalo en un lugar seguro. Y podemos usar eso para el resto del taller. Aunque si, como dije, tienes una API que también quieres usar, una API gráfica, entonces puedes usar esa en su lugar. Y pondré una en el chat de antemano.

Muy bien. Y déjame enviarte también un repositorio. Genial. Tenemos nuestro propio repositorio y básicamente solo tenemos un poco de plantilla para empezar. Así que compartiré mi pantalla y empecemos. Cambia mi punto final aquí. Asegurémonos de que estoy en el repositorio correcto. Genial. Así que lo que queremos hacer, es simplemente ejecutar NPMCI e instalaremos algunas dependencias. Y una de esas cosas que se instalará, oops, intentémoslo de nuevo. Una de esas cosas que se instalará será Rangler, que es una CLI de Cloudess para desplegar servicios, cosas así. Y en realidad vamos a necesitar Rangler para este proyecto, aunque lo estemos ejecutando localmente por ahora. Así que lo que quieres hacer es simplemente ejecutar, lo pondré en el chat. Npm bin Rangler login, algo así. Si estás en Windows, puede ser ligeramente diferente. Te dará un aviso para abrir un navegador y simplemente iniciar sesión con tu cuenta de CloudFlare. Te dará un aviso para abrir un navegador y simplemente iniciar sesión con tu cuenta de CloudFlare.

Genial, bien, voy a asumir que has iniciado sesión. Así que todos, si simplemente ejecutas ahora, npm run, creo que era dev, se llama a, oh sí, npm start, ahí vamos. Si estás en npm start, lo que vamos a hacer ahora es obtener un error de tipo, totalmente intencional, sabía que iba a pasar eso. Así que simplemente hagamos rápidamente, hagamos return null as any, y luego simplemente hagamos console log de la solicitud y veamos qué obtenemos. Y npm start, ahí vamos. Genial, en un segundo obtendrás un pequeño aviso, aquí vamos, que tenemos un servidor escuchando en este punto final. Y ahora básicamente podemos empezar a hacer solicitudes GraphQL a este punto final, deberíamos verlas registradas en la consola. Así que tengo un, tengo Insomnia aquí, pero puedes usar Postman o Kill o lo que quieras. Solo voy a hacer H7, H7. Genial, voy a hacer un informe rápido. Proximemos nuestra solicitud a eso. Y obtenemos un error, excepción de trabajo. Eso está totalmente bien, porque no devolvió nada. Pero lo que deberíamos ver es que el parámetro uno no tiene tipo.

2. Proxying Requests in Cloudflare Workers

Short description:

Vamos a realizar una solicitud de proxy en Cloudflare Workers utilizando solicitudes fetch. Haremos una nueva solicitud a nuestro punto final de GraphQL, tomando los detalles necesarios de la solicitud fetch. Si experimentas un error 403 al iniciar sesión en Wrangler, intenta ejecutar Wrangler in it para configurar tu proyecto. Si eso no funciona, intenta eliminar el archivo wrangler.toml y ejecutar wrangler inherit. Si Annet funciona, podemos continuar. Si encuentras errores al ejecutar Yarn start o NPM start, es probable que se deba a Annet en sí. Annet debería crear tu Wrangler y una instancia del worker en Cloudflare.

De acuerdo, vamos a ignorar eso. Realicemos una solicitud de proxy. Entonces, en Cloudflare Workers, puedes hacer solicitudes fetch. Por ejemplo, si queremos hacer una solicitud a Google, necesitamos algo como esto. Y es solo una solicitud fetch estándar como en el navegador. Y el entorno en el que estamos en un Worker de Cloudflare es básicamente, lo llaman Worker porque es como un service worker. Hay algunas restricciones en cuanto a lo que puedes hacer en el entorno. Pero en general, puedes hacer cosas como solicitudes fetch e interceptar solicitudes, cosas así.

Entonces, lo que vamos a hacer es, para empezar, simplemente vamos a hacer un fetch y vamos a hacer una nueva solicitud como parte de este fetch. El destino será nuestro punto final de GraphQL. Verás que tenemos un nuevo destino de solicitud, y el resto, el cuerpo, los encabezados, cosas así, simplemente los tomaremos de la solicitud que se nos pasa desde la función fetch.

Entonces, si hago rápidamente otra solicitud ahora, lo trabajaré en su sección. ¿Qué está pasando? Mmm, ¿alguien más está obteniendo este error? Pensé que podría haber roto algo antes. Supongo que no. Ahí vamos. Ahora funciona, bien, así que solo denme un pulgar arriba en el chat si no están obteniendo ese extraño error que definitivamente no esperaba. Echemos un vistazo. De acuerdo, Marken está obteniendo un 403, Rodrigo también está obteniendo un 403. De acuerdo, todos están obteniendo un 403. Eso probablemente significa, de acuerdo, cloud flag client V4 accounts, si, de acuerdo, estás obteniendo un 403 al iniciar sesión en Wrangler. Antes de comenzar, intenta ejecutar Wrangler in it para hacer lo mismo con npm bin si quieres algo así y, en teoría, estarás listo para continuar. Si te sientes cómodo haciendo eso, podemos agregar uno como consola. Podemos agregar uno y luego hacer un VERTX vacío y una vez que termine con eso, tengo una bandera oculta aquí. Solo una confirmación rápida en el chat si eso está funcionando ahora. Oh, ya veo. Hm, interesante. De acuerdo, echemos un vistazo rápido. De acuerdo, parece que lo que podrías necesitar hacer es simplemente deshacerte del, voy a probar esto muy rápidamente. Acabo de hacer un punto de interrupción. Y se corrompió y descubrí que es simplemente porque no es una API TrueType. Así que usaré el módulo normal. Si ustedes pueden... Sí. De acuerdo, lo que puedes hacer es simplemente deshacerte del wrangler.toml... Lo necesito. No. Si simplemente te deshaces de wrangler.toml por ahora, en tus proyectos. Y luego ejecutas wrangler inherit y en teoría, entonces eso debería crear un proyecto. ¿Cómo les va a ustedes? ¿Funciona ahora? De acuerdo. No te preocupes por eso por ahora. Mientras Annet funcione, lo que voy a hacer en realidad es, vamos a tomar el, instalé algo, pero ahora está fallando, igual que Marcus, de acuerdo. Y, ¿estoy en lo correcto al pensar que eso falla cuando ejecutas Yarn start ahora, ¿verdad, o NPM start? El Annet en sí, supongo que ha pasado. Oh, lo siento. Instalé algo y ahora está fallando, igual que Marcus. De acuerdo, genial. Entonces, si, lo que harías es, queremos usar ese Wrangler anterior que tenemos. Pero, lo que sucede en Annet, estoy bastante seguro de que necesito verificar esto. Ha pasado un tiempo desde que hice esto. Lo que hará Annet es probablemente crear tu Wrangler, pero también crear una instancia de ese worker en Cloudflare, que es lo que nos faltaba, por eso no funcionaba.

3. Solución de problemas de configuración de Wrangler

Short description:

Una vez que hayas ejecutado wrangler init, reemplaza el contenido del archivo wrangler. Si Wrangler in it no proporciona la configuración correcta, crea un nuevo proyecto y realiza cambios a medida que avanzas. Copia el directorio de origen, package.json y wrangler.toml en el nuevo proyecto. Intenta ejecutarlo en la instancia de desarrollo. Si aún obtienes el error 403, podría ser algo más.

Entonces, si verificas, éxito, error falso que falta, encabezados xolp xml. De acuerdo. Lo que sugiero que hagamos es, una vez que hayas ejecutado, así que elimina el wrangler toml, y luego ejecuta wrangler init, el comando previamente mencionado, y una vez que eso esté hecho, luego vamos a seguir adelante y reemplazar el contenido con esto, del archivo wrangler, y eso debería devolvernos a donde estábamos al principio, pero ahora con una instancia en Cloudflare.

Pensé que habría una forma más fácil de usar una configuración existente, gracias Fernando, puedes usar tu pantalla ahora. De hecho, puedo, sí, echemos un vistazo, así que caché GraphQL, perfecto, y si ejecutas esto, perdón si ejecuto esto, perdón, comando start. 403, interesante, intentando ver si hay algo aquí que sea específico de mi, específico de mi cuenta, pero, cuando hiciste Wrangler in it, ¿qué nombre le diste al proyecto? Creo que, oh, de acuerdo, en realidad puedo, puedo volver, simplemente, le gustó el nombre del repositorio. Interesante, qué sucede si intentas ejecutar eso, si lo ejecutas sin nada? Mm-hmm, así que guardé, ejecuté eso, luego se queja de que no tiene un punto de entrada. Entendido, sí, lo cual tiene sentido. Muy bien, mientras comenzamos, volvamos a 101, y escuchemos qué... Tengo una pregunta. Sí, adelante. En el mensaje, está escrito, distribución barra índice punto Jason, y si abres la carpeta, es index.NJS. Entonces, si abres la carpeta de distribución, genera un archivo completamente diferente. Así que ni siquiera entiendo esto. Oh, de acuerdo, cuando ejecutas Wrangler in it, creará una nueva configuración de Wrangler, pero no será la correcta, por eso estamos ejecutando Wrangler in it para crear el worker de Cloudflare en el lado del servidor. Y luego cambiarlo de nuevo a nuestra configuración. Así que tenemos los pasos de compilación que necesitamos. La cosa es que parece que no está, solo voy a intentar rápidamente hacer un nuevo trabajo con algo de Scratch. Echemos un vistazo. Creo que podría haber otra forma de hacer esto. Es difícil de probar. Parece que algo en esto es específico de mi, de mi cuenta. Y no estoy seguro de qué es. Si nadie ha encontrado una solución todavía, creo que para seguir adelante, lo que podemos hacer es crear un nuevo worker, desafortunadamente, y luego simplemente copiar cosas a medida que avanzamos. Lo que puedo decirte es que acabo de ejecutar lo siguiente. Lo siguiente, así que desde un directorio diferente, cualquiera que sea tu directorio principal, ejecuto esto y crea un nuevo proyecto. Y si entras en ese proyecto, parece funcionar bien. Así que tal vez lo que podemos hacer es comenzar con eso y luego en lugar de usar la plantilla que hemos creado, simplemente podemos hacer cambios a medida que avanzamos. Así que solo un resumen. Entonces, esos comandos entran en el directorio, haz una instalación de NPM y luego intenta, no sé sobre el comando start, echemos un vistazo rápido, y luego puedes ejecutar, quiero decir, deberías poder ejecutar eso y con suerte no verás errores 403. Asegurémonos de cambiar de directorio después de ejecutar rangler generate para que ingreses al proyecto recién creado, que creo que el nombre predeterminado parece ser mi worker. Bueno, comencemos moviendo la carpeta de origen. Solo muévela. Y también, porque estoy tratando de pensar cómo podemos hacer esto sin romper potencialmente esta plantilla. Quiero decir, el hecho de que eso funcione, lo que diría es que veas el wrangler toml ahora, cualquier cosa que no parezca específica de ese proyecto que acabas de crear. Entonces, por ejemplo, no UU ID o el nombre, que creo que es todo excepto el nombre, intenta copiar eso en el, de hecho, lo intentaré ahora antes de comenzar solo para no perder tiempo. Sí, lo curioso es que acabo de intentar cambiar el nombre del worker en mi repositorio, ver si eso lo rompe, pero realmente no estoy seguro de dónde se almacena esa configuración de wrangler, está en algún lugar de la tienda en la configuración, no sé dónde está. Pero de todos modos, sigamos adelante y copiemos esto. De acuerdo, lo que acabo de intentar ahora es crear un nuevo proyecto de wrangler y una vez que se crea ese proyecto, estoy copiando, básicamente reemplazando todo allí con ese repositorio original. Entonces el directorio de origen, el wrangler.toml, package.json, todas esas cosas buenas. Así que diría que pruebes eso. Creo que hay algo aquí que hace que wrangler no funcione, pero sí, diría que es un buen intento. Entonces intenta copiar el directorio de origen, el package.json y el wrangler.toml en el nuevo proyecto para reemplazar esos archivos y luego intenta ejecutarlo en la instancia de desarrollo. Si has visto lo mismo que yo, debería funcionar. No me funciona a mí, pero nunca antes he lanzado un worker con esta cuenta. ¿Quizás debería crear un dominio desde la interfaz de usuario o algo así? Así que en realidad no hice nada desde la interfaz de usuario. Sí, una vez que hice wrangler login y luego hice wrangler generate para crear el proyecto de wrangler, y luego desde allí hice algunos cambios para hacer la agrupación y demás. Tuve que configurarlo para este proyecto. Entonces, cuando ejecutas wrangler generate y luego entras en él, ejecutas npm install y luego wrangler dev, ¿eso funciona para ti o sigues obteniendo el 403? Cuando hago el npm start que hace el wrangler dev, todavía obtengo el mismo mensaje, el 403. Pero puedo ver mi ID de cuenta en esa URL, así que debe ser algo más.

4. Problemas de implementación de CloudFlare Workers

Short description:

Si has intentado generar wrangler y diferentes versiones de la CLI de wrangler sin éxito, es posible que necesites crear una cuenta separada para workers en Cloudflare. Una vez que tengas una cuenta de workers, el repositorio inicial debería comenzar a funcionar. Asegúrate de habilitar workers e iniciar sesión nuevamente. Al ejecutar npm start, la solicitud se implementa en Cloudflare y se realiza una proxy localmente. Puedes probarlo enviando una solicitud POST a localhost:8787. Actualmente, solo estamos reenviando la solicitud sin almacenar en caché.

Y si lo has hecho, ¿has intentado generar wrangler para crear un proyecto de wrangler completamente nuevo y luego intentar ejecutarlo? No, pero puedo intentarlo. He puesto algo en el chat. Solo verifica si eso funciona, creo. Oh sí, sí, lo hice, lo hice. Eso es lo que creó la carpeta de workers, sí, lo hice.

De acuerdo, ¿y ese está funcionando y obtienes un 403 al hacer eso? Todavía obtengo un error 403. Hombre, está bien, está bien. Todavía me pregunto si tenemos diferentes versiones de la CLI de wrangler y tal vez haya un... Permíteme echar un vistazo rápido. Tengo la versión 1.19.5 de wrangler. Hombre, esto es difícil de resolver. Intentemos eso. Permíteme echar un vistazo, ver si hay alguna forma de... Definitivamente estamos atascados. ¿Qué pasa si intentas hacerlo a través de un proyecto súper básico, como el generado, por ejemplo, sin copiar ninguno de los archivos, y luego intentas publicarlo y ver si eso nos hace avanzar. ¡Ja ja, de ninguna manera! Muy bien, chicos, encontré el problema y no es algo que ustedes hagan en nuestro propio bot muy pequeño. Resulta que debes crear una cuenta separada para workers en Cloudflare. Lamento mucho haberles hecho perder tiempo con esto. Si te registras en la URL de workers, si ya has creado una cuenta en tu estado, parece que aún debes crear una nueva para acceder a workers. No puedo creer que no me haya dado cuenta de esto, pero inténtalo y deberíamos poder seguir adelante. Es posible que debas iniciar sesión nuevamente. Sorpresa, estoy bastante sorprendido de que no obtengamos errores cuando intentamos iniciar sesión con la cuenta que no es de workers, pero inténtalo. Y es gracioso que por eso pregunté si teníamos que hacer algo en la interfaz de usuario porque. Sí, creo que tienes razón, en realidad. Creo que, sí, parece que debes optar por ello. ¿Dijiste que ya lo intentaste? Intenté hacerlo manualmente y avancé un paso más. Ahora tengo el problema del punto de entrada, pero creo que puedo solucionarlo editando la configuración. Así que en teoría, una vez que hayas, si tienes workers habilitados, solo voy a verificar rápidamente. Pero creo que una vez que tengas workers habilitados, ese repositorio inicial que hemos clonado debería comenzar a funcionar ahora. Pero sí, diría que simplemente intentes iniciar sesión nuevamente una vez que hayas habilitado workers. Y luego continúa desde allí. Solo voy a ver si puedo encontrar un enlace para habilitar workers. Genial, de acuerdo. Entonces, voy a asumir que todos están listos para continuar, pero voy a asumir que suena como que todos están en este paso. Entonces, en resumen, lo que acabamos de hacer es cuando ejecutamos npm start, se implementa en CloudFlare, y luego se realiza una proxy localmente para que podamos acceder fácilmente. Entonces, la razón por la que esto no funcionaba básicamente es porque no estaba implementado en CloudFlare. Pero una vez que te registres en esa cuenta de workers en lugar de una cuenta estándar, estamos listos para continuar. Así que, en este momento, muy, muy básico. Simplemente estamos reenviando esa solicitud. Entonces, lo que verás es si inicias algo como Postman o lo que sea y haces una solicitud POST al endpoint local host 8787. Y aquí tienes una consulta de ejemplo. Esta consulta debería funcionar para ti. La pondré en el chat en un segundo. Estamos obteniendo respuestas, lo cual es genial. Y eso es básicamente nuestro punto de partida. Entonces, si por alguna razón no tienes Postman o algo así, también puedes probar esta solicitud en tu terminal y deberías obtener una lista de usuarios. De acuerdo. Así que tenemos una solicitud entrante, y en este momento simplemente la reenviamos. Obviamente, eso no nos beneficia realmente, queremos detener la caché.

5. Identificación de Mutaciones en Consultas GraphQL

Short description:

Existen dos tipos de operaciones en GraphQL: mutaciones y consultas. Las mutaciones se utilizan para enviar datos, similar a las solicitudes POST en REST, mientras que las consultas se utilizan para la recuperación y almacenamiento en caché de datos. Para identificar si una consulta entrante es una mutación, podemos buscar en la cadena de consulta. Sin embargo, un enfoque mejor es utilizar un árbol de sintaxis abstracta (AST) para obtener una representación normalizada de la consulta. Al pasar la consulta a un AST, podemos analizar la jerarquía de la consulta y determinar el tipo de operación. Para hacer esto, podemos utilizar la función 'pass' de la biblioteca GraphQL JS, que convertirá la consulta en un objeto AST.

Entonces, hay dos tipos de operaciones para una consulta de GraphQL. ¿Alguien sabe cuáles son? Siéntete libre de escribirlo en el chat o decirlo en voz alta. En las mutaciones y las consultas. Sí, exacto, perfecto. Así que tenemos mutaciones y consultas entrantes y las que queremos almacenar en caché son obviamente las consultas porque eso es la recuperación de datos. Pero las cosas que no queremos almacenar en caché son las mutaciones porque obviamente eso envía datos, como las solicitudes POST en REST, por ejemplo.

Entonces, lo primero que debemos hacer es averiguar cómo identificar la consulta entrante como una mutación y luego actuar de manera diferente en función de eso. Entonces, lo que podríamos hacer es buscar en la cadena de consulta, tengo aquí algún código de ejemplo, solo para ahorrar tiempo. Aquí está. Así que tenemos un cuerpo aquí, que es request.body.text, que nos da la solicitud como una cadena de texto luego lo pasamos a JSON. Y cuando tenemos este cuerpo, hagamos un ejemplo, solicitud de ejemplo. Genial. Deberíamos ver algo aquí en algún lugar. ¿Estoy en la carpeta correcta? Sí. Obtenemos un objeto, vamos a convertirlo en una cadena para poder ver qué hay dentro. Ja ja, tenemos un objeto vacío. Clonar la solicitud como texto, luego analizar JSON. Genial. ¿Nos faltan algunos encabezados? Content-Type, application/JSON. Interesante. Para ser honesto, probablemente sea por JSON o algo así. Oh, ahí está, de acuerdo. Así que estamos obteniendo la consulta. Ves que tenemos la cadena aquí y probablemente la mayoría de ustedes saben que si queremos hacer una consulta, agregamos el prefijo `query` o simplemente omitimos el nombre de la operación por completo. Y si queremos hacer una mutación, agregamos `mutation` al principio de la cadena de consulta. Entonces, una mutación se vería algo así. Y luego agregamos `user`, por ejemplo. Entonces, lo que podríamos hacer es, ahora que tenemos esta consulta en nuestro cuerpo, podríamos simplemente pasar la cadena y buscar la palabra `mutation` en ella. El problema con eso es que es un poco rudimentario porque, al igual que cualquier tipo de recorrido de lenguaje, idealmente queremos obtener una representación normalizada del lenguaje que no incluya espacios, no incluya ningún tipo de variabilidad y se centre en lo que le importa a GraphQL.

¿Alguien está familiarizado con qué es un AST? ¿Puedes revisar el chat? Sí, tenemos uno de Rodrigo, genial. ¿Alguien más ha oído hablar de un AST? No, está bien, genial. Un AST significa árbol de sintaxis abstracta. Y puedes pensar en él como un paso después del análisis léxico. Así que pasamos la cadena a un léxico. Por lo tanto, esta consulta podría ser como un tipo de operación. Y luego creamos un árbol de jerarquía para que puedas iterar a través de esto y ver que tenemos una consulta y luego dentro de la consulta, tenemos campos y dentro de ese campo hay otro campo, y así sucesivamente. Entonces, para esto, lo primero que haremos es intentar pasar la consulta a un AST. Y luego lo siguiente que haremos es tratar de determinar qué tipo de operación se basa en eso. Entonces, lo primero que haremos y siéntete libre de seguir adelante es poner esto en el chat. Lo primero que haremos con nuestra consulta es en realidad hacer, se llama el documento de Haskell. Y llamaremos a `pass` que es de la biblioteca GraphQL JS que debería estar instalada en tu proyecto. Así que no te preocupes por eso. Y luego le pasaremos Body.query. Y si agregas un console.log y echas un vistazo al documento, deberías ver algo que es básicamente imposible de leer porque es solo un gran objeto desagradable. Echemos un vistazo. Ahí lo tienes. Entonces tendrás algo como esto, un objeto con el tipo de documento, algunas definiciones y luego información de ubicación. Hemos pasado la consulta y básicamente la cadena ya no es una cadena. Ahora es un AST, que es nuestra representación del documento, la consulta de GraphQL.

6. Explorando AST con astexplorer.net

Short description:

Para aprender sobre el AST, no queremos estar constantemente imprimiendo en la consola. En su lugar, podemos usar la herramienta astexplorer.net para explorar el AST de las consultas de GraphQL. Nos permite ver la estructura de la consulta y encontrar nodos específicos. Incluso podemos determinar si una consulta es una mutación examinando el AST. Tómate unos minutos para experimentar con la herramienta y no dudes en hacer cualquier pregunta en el chat.

Y lo que no queremos hacer es estar constantemente imprimiendo en la consola para aprender sobre el AST, porque, como puedes imaginar, hay muchos tipos diferentes de nodos AST. Hay este nodo de nivel superior, llamado documento, pero luego tenemos cosas como conjuntos de selección, campos, nombres, nodos, todo tipo de cosas que no necesariamente queremos leer una documentación masiva para entender.

Entonces, lo que vamos a hacer es ir a un sitio llamado astexplorer.net, que pondré en el chat aquí. Y esta es una herramienta increíble, solo voy a cerrar algunas de estas. Esta es una herramienta increíble, que te permite ingresar un lenguaje. Podría ser CSS, pero en nuestro caso, vamos a ir aquí y buscar GraphQL, que está aquí. Y luego puedes ver que realmente crea algunas consultas de ejemplo. Y luego, si haces clic, verás aquí a la derecha, muestra cómo se ve el AST. Por ejemplo, si quiero saber si este nombre aquí existe, quiero saber si este campo de nombre, pero no sé cómo encontrarlo en mi AST. Si hago clic, me llevará al nodo y me mostrará cómo existe en el árbol, lo cual es bastante útil.

Entonces, ¿alguien tiene alguna idea? Intentemos hacer una mutación. Mutación. Y podemos hacer, vamos a fingir que es una cosa aquí. De acuerdo, genial. Agrega una consulta, agrega una mutación. Y el desafío para ustedes ahora, el primero en hacerlo obtendrá puntos extra, porque eso es todo lo que tengo para ofrecer en este momento, pero pensaré en algo mejor. Pero jueguen con estas consultas, hagan clic y vean si pueden descubrir cómo identificar si es una consulta o una mutación basándose en este nodo aquí. Les tomará un par de minutos hacerlo. Y mientras tanto, si tienen alguna pregunta, solo escríbanla en el chat. Sí. Y nos preparamos para continuar.

7. Determinando Operación de Consulta o Mutación

Short description:

Te enviaré un enlace. Si estás atrasado, revisa la rama de progreso. Avísanos si tienes alguna pregunta o problema. Rodrigo ha identificado la operación de consulta. Podemos determinar el tipo de operación sin analizar cadenas. Verificamos si el tipo es Definición de Operación y si la operación es una consulta. Lo probamos con una consulta y una mutación. Verdadero para consulta y falso para mutación.

De acuerdo. Muy bien. Acabo de recibir tu mensaje, Muhammad. Te enviaré un enlace. Ahora. Te enviaré un enlace. Oye Muhammad, crearé una rama separada con el estado actual de lo que estoy haciendo solo para que ustedes, aquellos que están atrasados, puedan revisar esa rama. Genial. Así que cualquiera que quiera ponerse al día si siente que está un poco atrasado, tal vez si tuvo algunos problemas configurando Cloudflare, una vez que estés listo, solo revisa, hay una rama de progreso , solo revisa eso y deberías poder avanzar con eso. Pero también deja un mensaje en el chat o habla si sientes que tienes alguna pregunta o tienes algún problema. Todos tenemos entornos diferentes, como se demostró anteriormente. Entonces, lo que funciona para mí puede que no funcione para ti, así que definitivamente avísanos.

Probablemente no tendrás ese problema si estás teniendo problemas. ¿Alguien está cerca de encontrar algo en el árbol AST que pueda dar una pista sobre qué tipo de operación estamos trabajando? Perfecto, para Rodrigo, una leyenda. Sí, Rodrigo lo ha clavado. Básicamente, todo esto aquí es lo que consideramos un documento. Y dentro del documento, la cosa de nivel superior, entonces lo siguiente es una definición. Y podemos tener muchas de esas. Como puedes ver aquí, tenemos dos. Tenemos una definición de operación y una segunda definición de operación. Y si entramos en esta primera aquí, verás que hay una clave de operación, que es consulta. Entonces esto nos dice que sin siquiera tener que preocuparnos por qué texto hay aquí, si hay una consulta aquí o si esta es una consulta válida también, pero no tiene el texto consulta, pero aún así dice OperaciónConsulta, hace el trabajo por nosotros de determinar qué operación es, lo cual nos ahorra tener que hacer análisis de cadenas y cosas así.

Entonces lo que podemos hacer es, de hecho, voy a intentar copiar y pegar el ejemplo de Rodrigo allí. Voy a decir que esConsulta es igual a, vamos a tomar esto. Lo que vamos a hacer es document.definitions.some. Solo voy a decir nodo, que nos da cada definición. Voy a decir si el nodo.kind es igual a, voy a importar kind desde aquí. Kind es solo un enum que nos permite hacer kind.operation.definition. Genial, vamos a decir en nuestras definiciones, tenemos un nodo que es de tipo kind.operation.definition y node.operation es igual a consulta. Aprecio que esto no se esté envolviendo. Permíteme ver si puedo activar el ajuste de línea para ustedes. Ahí vamos. Genial, como Rodrigo compartió, vamos a buscar en esas, ese documento que tenemos, el documento AST. Buscamos definiciones, verificamos si el tipo es Definición de Operación. Así que solo vemos, ¿tenemos una que sea Definición de Operación? Y si es así, ¿es la Definición de Operación de tipo consulta? Pondré esto en el chat para cualquiera que no esté usando algo como Postman.

8. Manejo de Consultas y Mutaciones con Proxy

Short description:

Ahora tenemos la capacidad de determinar si es una consulta y si es una mutación, lo cual es genial. Vamos a empezar a ramificar en esta función fetch aquí, así que vamos a sacarla y crear las funciones handleMutation y handleQuery. Deberíamos tener dos manejadores casi idénticos, ambos simplemente hacen un proxy en este momento. Según si es una consulta o no, llamaremos al manejador apropiado. Queríamos almacenar en caché una consulta, pero no las mutaciones. Para almacenar en caché una consulta, utilizaremos un almacén KV ofrecido por Cloudflare. Ejecuta los siguientes comandos: [comandos].

O un GraphQL playground o algo así. Aquí hay un ejemplo de consulta y, ups, eso es una mutación. Consulta y consulta, ahí vamos. Genial, ¿tiene sentido hasta ahora para todos? Solo un pulgar hacia arriba rápido en el chat, tal vez. Ahora tenemos la capacidad de determinar si es una consulta y si es una mutación, lo cual es genial.

Ahora lo que queremos hacer es que vamos a empezar a ramificar en esta función fetch aquí, se va a poner bastante grande, así que vamos a sacarla y vamos a hacer una función handleMutation y también vamos a hacer una función handleQuery. Vamos a hacer un handle. Y solo para ahorrarnos analizar la consulta dos veces, vamos a pasar la consulta así y luego vamos a devolver un manejador de eso. Y vamos a devolver un manejador de eso. Dale una solicitud, ups, y pondré una plantilla rápida aquí. Así que deberías tener algo como esto, uno para handleMutation, uno para handleQuery. Y solo para que CloudFlare esté contento al principio, asegurémonos de tener siempre ese proxy que hicimos antes, el return fetch para la solicitud y todo eso. Y eso se asegurará de que siempre volvamos a reenviar esa solicitud si no la manejamos de ninguna manera en particular. Genial, así que deberíamos tener, lo pegaré en el chat. Básicamente deberíamos tener dos manejadores casi idénticos, ambos simplemente hacen un proxy en este momento.

Lo que vamos a hacer ahora es, según si tenemos isquery es verdadero o no, vamos a tomar el manejador apropiado. Así que hagamos return isquery. Si es una consulta, entonces vamos a llamar a handleQuery, pasándole nuestro documento que ya hemos pasado, y también pasamos las solicitudes y ctx. ¿Qué pasa con este documento? Lo siento, gente, el documento debería ser document node, y necesitamos asegurarnos de importarlo desde GraphQL. Ahí vamos. Entonces, si es una consulta, vamos a llamar a handleQuery, de lo contrario vamos a llamar a handleMutation, y eso se verá algo casi idéntico, solo que en lugar de consulta, será mutación. Genial, y luego podemos deshacernos de este fetch, la bomba. Ahí estamos. Lo pegaré de nuevo en el chat ahora que los errores de tipo están solucionados. Algo así. Solo un pulgar hacia arriba rápido en el chat. ¿Esto tiene sentido para la gente? Así que está ahí ahora. Muchas gracias, game. Como amigo, siempre estoy emocionado cuando apareces en cualquier cosa, es genial contactarte. Siento que es algo positivo para todos aquí. Nuestro próximo invitado que está en un día muy ocupado aquí. Es mi amigo del podcast de C++ de la semana pasada. Así que, si quieres echarle un vistazo, sabes, el trabajo complicado de determinar si es una consulta o no lo hemos hecho. Ahora solo estamos manejando la consulta o la mutación según la respuesta. Como hablamos antes, queríamos almacenar en caché una... Solo asegurémonos de que no me esté saltando ningún paso aquí. Sí, genial. Así que queríamos almacenar en caché una consulta, pero no queremos almacenar en caché las mutaciones. Entonces, para almacenar en caché una consulta, porque estamos trabajando en Cloudflare workers, no podemos permitirnos mantener las consultas en memoria porque esos workers tienen una vida útil corta. Por lo tanto, podrían ser completamente eliminados en cualquier momento. Y también pueden ejecutarse concurrentemente como la mayoría de las ofertas serverless. Así que imagina que tienes tres workers y todos se ejecutan al mismo tiempo, todos tienen su propia versión de una caché, lo cual puede ser un poco agitado. Queremos solucionar eso. Entonces lo que vamos a hacer es vamos a usar lo que se llama un almacén KV y Cloudflare nos lo ofrece. KV significa solo clave valor. Y te voy a enviar. Sí. Entonces, deberás ejecutar los siguientes comandos. Es posible que debas agregar MPM antes de Wrangler, no tienen ningún plugin como ese para tu directorio binario.

9. Creación de Espacios de Nombres KV y Configuración de Wrangler

Short description:

Vamos a crear dos espacios de nombres: type names too y responses. Asegúrate de agregar el ID y el ID de vista previa a tu archivo Wrangler.toml. El ID de vista previa garantiza que se utilice el almacén KV al ejecutar Wrangler localmente. Si tienes el espacio de nombres responses con los IDs correctos, estás listo para continuar.

Pero lo que vamos a hacer aquí es simplemente crear los dos espacios de nombres. Y cuando ejecutes eso, deberías recibir algún tipo de notificación de que el espacio de nombres ha sido creado. De hecho, hagamos un ejemplo rápido. Así que voy a crear uno nuevo llamado type names too. No puedo hacer type names too. Intentémoslo de nuevo. Type names too. Genial. Y verás que deberías obtener algo como esto, que te indica que agregues lo siguiente a tu archivo Wrangler toml. Así que vamos a hacer exactamente eso. Si incluso puedes copiar esto cruzado a tu Wrangler.toml Vamos a ponerlo aquí arriba en algún lugar. Y hay un cambio que vamos a hacer. Que es para este ID aquí, que declara el ID del espacio de nombres KV, que vamos a llamar responses. Creo que era eso. Ya los he creado antes, así que solo quiero asegurarme de no crear nuevos. Así que cuando peguemos esto, obtenemos un ID. Pero lo que verás es que en realidad también necesitamos el ID de vista previa. Así que lo que puedes hacer es copiar ID igual aquí. Agregar una coma y luego pegarlo nuevamente. Pero esta vez voy a poner ID de vista previa. Y todo esto hará es indicar que cuando estemos ejecutando Wrangler localmente, ejecutando Wrangler dev, queremos usar el mismo almacén KV también. Así que sí, por ahora podemos hacer solo uno. Mientras tengas uno llamado responses, todo en mayúsculas, y tengas el ID y el ID de vista previa iguales, entonces deberíamos estar listos para continuar. Y solo danos un pulgar hacia arriba en el chat si estás listo para continuar. Parece que Rodrigo está al tanto. Así que asegúrate de que cuando pegues eso desde la CLI, como dice allí, enlace de espacios de nombres KV, asegúrate de que el ID de vista previa sea igual al ID.

10. Trabajando con Espacios de Nombres KV en Wrangler

Short description:

Ahora podemos usar Wrangler dev para apuntar al espacio de nombres KV. El espacio de nombres KV se expone como end.responses, lo que nos permite realizar operaciones como agregar, obtener y eliminar pares clave-valor. Comencemos probando una operación de agregar con la clave 'one' y el valor 'hello'. También podemos hacer esto de forma asíncrona e intentar obtener el valor y registrarlo en la consola. Tenemos un almacén de clave-valor funcional y podemos escribir datos en él. La clave que estamos usando es 'responses'.

Y una vez que tengas eso, ahora tenemos, cuando ejecutamos Wrangler dev, lo cual estamos bastante seguros de que probablemente tendremos que ejecutar de nuevo Voy a iniciarlo de nuevo, solo para... ¿Qué es? YARM dev start, NPM start, ahí vamos. Genial. Ahora teóricamente debería estar apuntando al espacio de nombres KV. Y lo que podemos hacer ahora es, la forma en que el espacio de nombres KV se nos expone usando Wrangler es ver esto end. Así que he agregado algunos tipos para ti, verás si haces end punto, verás que tienes responses y type names. Por ahora solo nos preocuparemos por responses. Tenemos end.responses, y desde allí podemos hacer, tenemos un almacén básico de clave-valor. Así que podemos comenzar a agregar cosas, obtener, eliminar, etc. Entonces, con lo que podemos comenzar es, intentemos con una consulta, inténtalo haciendo end.responses. Digamos, put, pongamos clave uno, hola. Así que intenta hacer eso, intenta hacer algún tipo de agregar y tal vez, hagamos esto de forma asíncrona, y tal vez intentemos obtener eso también en la consola con console.log y veamos si puedes hacer que funcione. Y tal vez, bien, así que tenemos un almacén de clave-valor y podemos escribir cosas en él. ¿Alguien quiere intentar adivinar qué vamos a escribir en nuestro almacén de KV? Ok, si alguien piensa que es responses, estás en lo correcto.

11. Almacenamiento en caché de respuestas en el almacén KV

Short description:

Vamos a obtener la respuesta y almacenarla en nuestra caché. La caché será un almacén de clave-valor donde la clave es la consulta y el valor es la respuesta. Vamos a convertir la respuesta en una cadena antes de almacenarla. La idea es que cuando se realiza una consulta, comprobaremos si está en la caché. Si lo está, devolveremos la respuesta en caché. Si es una nueva consulta, obtendremos la respuesta, la agregaremos a la caché y devolveremos la respuesta.

Lo que vamos a hacer en nuestro manejo de consulta aquí, en lugar de simplemente devolver la respuesta, es que vamos a intentar primero una nueva espera. Hagamos una nueva respuesta igual a una espera de fetch. Genial. Una vez que obtengamos esa respuesta, queremos comenzar a ponerla en nuestra caché. Así que antes de continuar, voy a darte una visualización rápida de cómo queremos que se vea nuestra caché. Es un almacén KV, lo que significa que tenemos K, que es clave y luego valor, que es pesado, que es valor. Así que se verá algo como esto. Ahora, por ahora, lo mantendremos bastante básico. Solo tendremos nuestra clave como la consulta. Por ejemplo, consulta usuarios, tendremos el valor como la respuesta. Y en realidad vamos a convertir eso en una cadena. No sé si es necesario o no, pero creo que sí. Siéntete libre de probarlo sin convertirlo en cadena. Avísame si funciona, pero tendremos nuestra respuesta, que será nuestro data, que podría verse algo como esto y así sucesivamente. Así es como se verá nuestro almacén KV internamente. Y en teoría, lo que sucederá es que cuando hagamos esta primera consulta, haremos esa solicitud y comprobaremos la respuesta, veremos lo que obtenemos de la respuesta, y si es un éxito, lo escribiremos en la caché y la próxima vez que llegue esa consulta, devolveremos una respuesta en caché. Y si es una nueva consulta, entonces repetimos el proceso, hacemos la solicitud y luego la agregamos a la caché.

12. Análisis y almacenamiento en caché de la respuesta

Short description:

Voy a mostrarte rápidamente cómo analizar la respuesta clonándola y obteniendo el JSON. Comprobaremos si la respuesta está bien y no tiene errores. Luego la escribiremos en la caché utilizando la consulta como clave. Convertiremos la consulta en una cadena utilizando la función print. Por último, devolveremos la nueva respuesta al cliente que la solicita.

Voy a mostrarte rápidamente, te mostraré rápidamente cómo analizar la respuesta porque no es muy obvio e incluso he tomado nota en algún lugar porque, porque, oh, vale, ahí vamos, vale, genial. Así que lo que podemos hacer es nuevo JSON es igual a nueva respuesta.punto Jason. Voy a clonarlo y todo lo que hace el clon es crear como una nueva instancia de esa respuesta. No vuelve a buscar ni nada por el estilo. Solo significa que cuando intentamos leer de ella, si intentamos leer de la misma respuesta dos veces o error, lo cual puede ser un problema si leemos de una respuesta y luego devolvemos esa respuesta más adelante. Así que en nuestro caso, simplemente lo clonaremos y obtendremos el JSON. Y de hecho, antes de hacer eso, hagamos una comprobación rápida. Así que si la nueva respuesta está bien, es decir, obtenemos una respuesta exitosa y no hay errores. Queremos asegurarnos de que no haya errores gráficos. Así que digamos que no hay error en la respuesta. Bueno, tenemos un problema aquí. Hagamos, genial. Entonces diremos que la respuesta está, bien, es un 200 o un 201 o lo que sea. Y no tenemos un error. Luego, lo que haremos es escribir esto en la caché, lo cual todos ustedes ya han hecho. Así que simplemente haremos esto y la respuesta será, vamos a hacer una clave, que será nuestra consulta. Y en realidad vamos a tener que convertir esto en una cadena. Para hacer eso, en lugar de usar POS, que toma la cadena de consulta y la convierte en una consulta, AST, vamos a usar print. Y eso es básicamente lo contrario. Así que toma el AST y lo convierte en una cadena. Así que hagamos print y luego hagamos nuestra consulta. Y luego el valor, como dije, siéntete libre de probar esto sin una cadena. Puede que no sea necesario convertir esto en una cadena. Lo que vamos a capturar es obviamente la respuesta. Así que vamos a capturar el nuevo JSON. Luego, hagamos un pequeño registro en la consola, igual que la caché de consulta. Genial, tenemos nuestra respuesta, está bien. No hay errores, lo estamos almacenando en caché, pero eso no es suficiente porque obviamente todavía necesitamos permitir que el cliente solicitante obtenga los data. Así que lo que podemos hacer muy fácilmente, es simplemente devolver esa nueva respuesta también, la respuesta completa, todos los encabezados, todas esas cosas buenas. Así que haz una prueba y veamos si puedes hacerlo. Pondré el ejemplo aquí, juega con él, tal vez intenta... tal vez intenta algo un poco diferente. Ve si se te ocurre algún otro caso especial que podríamos estar pasando por alto, y luego simplemente ve si puedes capturar la consulta por nosotros. Compartiré rápidamente mi pantalla para marcar. Si no almacenamos esto en caché, comenzaremos a tener problemas con el JSON desconocido. Así que simplemente lo convertimos todo en any así pasando el genérico debería ayudarnos. Y también, no estoy muy seguro, pero sospecho... Sí, asegúrate por ahora, si alguien lo ha intentado sin definir una cadena, avísame. Los objetos podrían funcionar en lugar de una cadena. Pero sí, por ahora, intentaré envolverlo en una cadena, y deberías obtener una cadena para el tipo de retorno de print, y luego una cadena para el tipo de retorno del stringify también. Y de nuevo, hagamos una comprobación rápida... Genial, la rama de progreso está actualizada. Así que si quieres incorporar eso, puedes hacerlo. ¿Cómo les va a todos los demás, cómo se están manejando?

Vale, genial. ¿Alguien tiene problemas? ¿Alguien todavía está bloqueado o estamos obteniendo errores de tipo? Solo escríbelo en el chat o siéntete libre de hablar en voz.

Muy bien, genial. Si, no tiene que ser Rodrigo, ¿alguien tiene ideas de cómo podemos devolver ahora este valor en caché? Siéntete libre de encender tu micrófono si quieres. Hasta ahora, hasta este punto. Hola, seguro, Muhammad.

13. Caching Responses and Retrieving from Cache

Short description:

Tenemos un worker que maneja las solicitudes de GraphQL, determinando si es una consulta o una mutación. Si es una consulta, la manejamos en consecuencia. Si es una mutación, reenviamos la respuesta. Hemos creado un almacenamiento KV para almacenar en caché las respuestas exitosas. Ahora intentamos recuperar una respuesta de la caché. Si se encuentra, la devolvemos. De lo contrario, creamos una nueva respuesta y la almacenamos en la caché. También agregamos una cabecera para indicar un acierto de caché.

Una cosa que diría es simplemente, una vez que hayas comprobado la rama, siéntete libre de ejecutar esto y obtener los últimos cambios que podrían ayudarte a ponerte al día si sientes que estás un poco rezagado. Pero hasta ahora lo que hemos hecho es tener un worker que recibe una solicitud de GraphQL. Y lo primero que hacemos es determinar si es una consulta o una mutación. Y si es una consulta, vamos a manejarla de lo que hablaremos en un segundo. Y si es una mutación, pasamos a manejar la mutación que simplemente reenvía esa respuesta al origen.

Entonces, el origen está aquí, por cierto. En este caso, es solo un punto final falso de GraphQL. Y lo que acabamos de hacer en los últimos 10, 15 minutos es crear un almacenamiento KV en Cloudflare que es como un diccionario o almacenamiento de objetos. Y lo que estamos haciendo ahora es, cuando recibimos una consulta, hacemos la solicitud pero en lugar de hacerlo como con la mutación donde simplemente devolvemos la respuesta de inmediato. Esta vez, lo que estamos haciendo es comprobar si la respuesta es exitosa y si lo es, la almacenamos en caché. Así que la almacenamos aquí en nuestras respuestas donde la clave es la cadena de consulta y el resultado es la respuesta. Y luego devolvemos la respuesta original del origen. Y lo siguiente que vamos a hacer ahora es devolver esa respuesta de la caché. Y obtenemos nuestros resultados. Y en realidad, hablaremos de eso un poco más tarde. Pero por ahora, hagamos algunas tareas simples aquí.

Vamos a ir y nombrar nuestro archivo. Y vamos a revelar un mensaje. Tenemos un problema con el archivo de operaciones. En realidad, podemos deseleccionar este archivo y luego tenemos una copia de la salida. Digamos que tengo un sitio web que puedo usar Así que tenemos una respuesta en caché. Y esto está ahora en el almacenamiento. Y básicamente estará allí para siempre. Así que incluso si no hacemos solicitudes durante un año a partir de ahora, todavía estamos seguros de que KVstore aún tiene un estado y seguirá actualizado. Así que lo que necesitamos hacer ahora es intentar antes de hacer esta parte aquí, que es una nueva respuesta. Así que esto es básicamente como una respuesta fresca, ya sabes, la respuesta fresca antes de reenviarla al origen. Lo que podríamos hacer es intentar ver si podemos, vamos a intentar ver si podemos obtener algo de la caché. Así que primero intentaremos obtener algo de la caché. Entonces hagamos una constante respuesta de caché igual a esperar, y luego vamos a ir a respuestas, que nos da nuestro kv.get. Y luego vamos a imprimir nuestra consulta. Y solo para limpiar un poco las cosas, porque imprimir no es muy barato, hagamos una rápida, movámoslo todo allí. Así que solo lo llamamos una vez. Vamos a intentar obtener la respuesta de la caché, así. Así que simplemente decimos, obtener, y proporcionamos la clave, que es, como puedes ver aquí, cuando lo escribimos, y la clave es la cadena de consulta. Y luego lo que vamos a hacer es si hay una respuesta de caché, vamos a devolver la respuesta de caché. De hecho, vamos a tener que hacer un poco más que eso. Vamos a tener que crear una nueva respuesta. El cuerpo va a ser, vamos a verificar esto de nuevo, tal vez no esto antes. Ahí vamos. Genial. Así que vamos a devolver nuestra nueva respuesta. Vamos a devolver la respuesta de caché, que es esa cadena de objetos stringificados. Y luego, tenemos que asegurarnos de que le informamos al cliente que es un objeto y no solo una cadena aleatoria. Así que tenemos content type application, JSON. Y solo como un bono adicional, vamos a agregar aquí una cabecera llamada x-line. Así es como la vamos a llamar. Entonces se llamará X-Cache-Hit. Y lo pondremos como verdadero. Y lo que eso significa es que si guardo esto, espero a que se reconstruya. Hagamos un registro rápido. Gran mensaje de caché.

14. Caching and Invalidating Queries

Short description:

Si hago mi consulta y luego verifiquemos aquí. X-Cache-Hit verdadero. Lo que significa es que la consulta pasó y se almacenó en caché. Si cambio mi consulta, no hay acierto de caché porque es una nueva consulta. Si la ejecuto nuevamente, boom, X cache hit es verdadero. Y verás que obtenemos la consulta en caché.

Compilación exitosa. Genial. Entonces, si hago mi consulta, y luego verifiquemos aquí. X-Cache-Hit verdadero. Lo que significa es que la consulta pasó y se almacenó en caché. Y si cambio esto, digamos que cambié mi consulta, solo le daremos un nombre por ahora. Mi consulta única. Enviar. En teoría, verás que no hay acierto de caché allí porque esta es una nueva consulta. Entonces, no está en nuestro almacenamiento KV. Si lo ejecuto nuevamente, boom, X cache hit es verdadero. Y verás que obtenemos la consulta en caché. Entonces, lo que voy a hacer, es simplemente pegarlo en el chat y también actualizaré la rama. Genial. Démosle un par de minutos a las personas para que lo prueben.

15. Caching and Invalidating Queries

Short description:

Imagina que has realizado una consulta y la hemos almacenado en caché. Cada vez que solicites el usuario con este ID, siempre obtendrás la misma respuesta. Si una mutación cambia al usuario y se vuelve a realizar la consulta en caché, el resultado ya no es válido y debe ser invalidado. La introspección y los esquemas de GraphQL proporcionan información de esquema para cada pieza de datos, incluidos los nombres de tipo. Al utilizar los nombres de tipo en combinación con algún tipo de ID, podemos identificar de manera única los nodos y actualizar consultas específicas sin tener que volver a buscar todas las demás.

Este es un ejemplo muy rápido. Tenemos una consulta y decimos, obtener usuario con ID uno y obtenemos el ID, el nombre y la edad. Solo vamos a obtener el ID y el nombre, está bien. Imagina esto, imagina que has realizado esta consulta y la hemos almacenado en caché. Esta consulta ahora está en la caché. Cada vez que solicites este usuario con este ID, siempre obtendremos la misma respuesta. Luego llega esta mutación. Lo que sucede es que alguien desencadena una mutación que cambia al usuario. Y luego esta consulta llega más tarde y devolvemos el resultado en caché nuevamente. El problema con el resultado en caché es que ya no es válido y debemos invalidarlo. Como dijo Rodrigo. ¿Alguna idea, algún pensamiento sobre qué podríamos hacer para abordar esto? Echemos un vistazo al chat. ¿Cómo podríamos ver una mutación y luego averiguar qué hacer? Podríamos invalidar todas las consultas. Podríamos decir que cada vez que llegue una mutación, borraremos todo el almacenamiento de clave-valor, pero obviamente eso no es ideal, pero tal vez haya otras cosas que podamos hacer también. Invalidar solo los campos mutados restringe todo el KB. Sí, creo que estás más cerca de lo que crees, Rodrigo. Hay algunas cosas bastante advanced que podríamos hacer aquí. Para estos propósitos, vamos a ver lo que hicimos en la URL con la caché ingenua. Entonces, una cosa que no mucha gente sabe sobre esto, es una de esas cosas que a menos que hayas necesitado usarlo, probablemente no lo hayas hecho. Pero con GraphQL, la razón por la que podemos crear clientes de GraphQL que tienen su propia caché y son inteligentes y saben cuándo invalidar las cosas es debido a la introspección. Entonces, si piensas en tu API REST y haces una solicitud a una ruta, y obtienes data de vuelta, realmente no sabemos qué es esa data. ¿Es un, podemos mirar la URL e intentar hacer suposiciones, pero realmente no hay mucha confianza en, ¿es esto un usuario? ¿Es este un usuario con, no sé, un campo que dice amigos con más usuarios o un campo que dice organizaciones con organizaciones. Y es realmente difícil saber qué tipo de data estamos trabajando. Entonces, lo realmente genial de GraphQL es que tenemos introspección y esquemas. Y cada pieza de data que obtienes realmente tiene información de esquema. Entonces, si alguna vez has oído hablar del nombre de tipo, que se ve un poco así con un doble guion bajo y luego nombre de tipo. Esto es realmente para eso. Entonces, si hago una solicitud rápida ahora para una consulta y busco, dame todos los usuarios y dame el nombre de tipo, verás que en realidad ahora devuelve el nombre de tipo y ese campo tiene un valor de usuario. Entonces, lo realmente genial de esto es que ahora sabemos que este objeto aquí al menos es un usuario. Y si este objeto tiene algunas relaciones, también podemos ver los tipos de esas relaciones. Así que eso es bastante útil. Y eso significa que ahora sabemos que este es un usuario con ID tres o este es un usuario con ID tres. Y en realidad podemos identificar de manera única los nodos. Entonces, si imaginas que hacemos esta solicitud dos veces, imagina que obtuviste esta respuesta dos veces. Solo voy a deshacerme de eso. Genial. Obtenemos ID tres edad 24, primer nombre Estelle. Y luego tenemos ID tres primer nombre Estelle. Hagamos esto un poco más ambiguo. De acuerdo. Entonces tenemos ID tres nombre Estelle, ID tres nombre Jess. Solo, si asumimos que ID tres corresponde a la misma entidad, terminamos con problemas porque ¿qué pasa si ID tres nombre Estelle es, no sé, ¿qué pasa si este era el nombre de una empresa y este es el nombre de un usuario? Entonces, ¿qué pasa si esto es como Estelle limitada o algo así, ¿verdad? Y eso es totalmente válido. Puedes tener IDs que son idénticos pero para cosas diferentes y no significa que sean lo mismo pero al introducir los nombres de tipo en la mezcla, la comp B, okay vamos a agregarlo manualmente. Entonces, si agregamos el nombre de tipo usuario usuario y luego tenemos lo mismo aquí. Bueno, ahora que sabemos que esto es un usuario con ID tres y aquí sabemos que esto es un usuario con ID tres. Entonces, lo genial de esto es que al usar el nombre de tipo en combinación con algún tipo de ID, ahora sabemos que cada vez que obtenemos un por ejemplo, si hacemos esta consulta y luego más tarde hacemos una consulta diferente que devuelve ID tres en tipo usuario y cambia el nombre. No necesitamos volver a buscar todas nuestras otras consultas. Podríamos simplemente actualizar esto. Y eso es lo que hacen muchos clientes Ercle, Apollo, Relay, mirarán el realmente crearán una tienda que se ve algo como esto, la cantidad de como org uno, dos, tres, cuatro. Y en realidad almacenarán listas normalizadas de todos estos objetos para un nombre de tipo dado.

16. Caché y Modificación de Consultas con AST

Short description:

Podemos identificar de manera única las entidades utilizando una combinación de nombre de tipo e ID. El alias en GraphQL nos permite consultar datos con diferentes nombres. El cliente de GraphQL puede manejar los alias revirtiéndolos a la representación normalizada. Simplificaremos el proceso de caché al ignorar el ID y centrarnos en el nombre de tipo. Las mutaciones deben devolver la entidad modificada, incluido el nombre de tipo. Agregaremos el nombre de tipo a la solicitud de mutación e invalidaremos las consultas basadas en él. Utiliza AST Explorer para explorar el AST y realizar los cambios necesarios. Comprender la estructura del AST es clave para modificar la consulta.

Y cuando se actualiza en un lugar en lugar de obligar al usuario a volver a buscar todas las consultas simplemente actualiza el estado para tener el último usuario tres porque sabemos que es la misma entidad. Así que eso puede sonar un poco complicado. Siéntete libre de hacer preguntas en el chat si quieres. Definitivamente no es una idea fácil de entender pero la forma general en que puedes ver esto es con una combinación de nombre de tipo e ID podemos descubrir, podemos identificar de manera única las entidades y saber que nos referimos a lo mismo porque un ID nunca va a cambiar y el nombre de tipo nos dice qué tipo de cosa estamos trabajando.

Chat, ¿cómo manejan los alias? Si tienen un ejemplo de un alias, Roger, adelante. Entonces, ¿cuándo mutas algo, bueno no mutas, pero tal vez consultas algo con un nombre diferente? Como por ejemplo, en lugar de nombre, no sé, ¿lo alias a un nombre completo? Y luego. Cuando dices alias, ¿te refieres a la consulta? Sí, sí, exactamente. Ah, okay, seré honesto, no estoy muy familiarizado con los alias de GraphQL, pero supongo que hay una forma de hacer algo como esto, supongo que lo que estás diciendo es algo como esto, y luego necesito el tiempo y cosas así. Sí, sí, exactamente. Oh, perfecto, entonces en el caso de cualquier cliente de GraphQL, porque es el que realiza esa solicitud saliente, puede saber que hay un alias presente, por lo que básicamente puede mirar la solicitud saliente, decir, oh, aquí hay un alias, así que cuando reciba la respuesta, debo asegurarme de que el respondedor normalizado, revierta el alias para obtener la representación normalizada, y también cuando actualicemos otras consultas, debemos asegurarnos de que sepamos que el alias existe. Por lo general, estamos tratando de realizar un seguimiento de qué consultas tienen alias, cuáles no, y qué alias hay, para poder moverlos. Pero sí, eso es en realidad una caché normalizada, y vamos a hacer algo similar. Vamos a utilizar un enfoque más simple para esto, así que en lugar de preocuparnos por el ID del usuario tres, el ID del usuario cuatro, y así sucesivamente, vamos a olvidar el ID. Entonces, cuando alguien realiza una mutación como actualizar usuario, ID uno, dos, tres, cuatro, nombre, nuevo nombre. Las mutaciones típicamente... Los ídolos son devolver la cosa que ha sido cambiada. Entonces, en teoría, lo que deberíamos obtener de actualizar usuario es el nuevo usuario, el nuevo usuario con ID y nombre, y en este caso, nombre de tipo. Entonces, lo que vamos a hacer es hacer un par de cosas primero. Nos aseguraremos de que el nombre de tipo esté en la solicitud de la mutación. Así que lo agregaremos a la mutación para incluirlo. Y luego también vamos a... Más adelante, no necesitamos hacer eso todavía. También vamos a intentar invalidar las consultas basadas en esto. Entonces, la primera tarea, les daré unos minutos para que lo intenten. Echen un vistazo al AST en AST Explorer. Por ejemplo, este usuario uno aquí con un ID y tal vez un nombre. Y digamos, por ejemplo, que este usuario también tiene un empleador que es la versión que también tiene, oops, un ID y, no sé, solo un ID por ahora. Muy bien, aquí está lo que tenemos antes. Una consulta que se ve así. Y aquí está lo que queremos después. Oops. Muy bien. Así que lo voy a poner en el chat y les daré cinco minutos para que lo pongan en AST Explorer y vean si pueden descubrir. Oh, lo siento, el formato no está del todo bien. Y vean si pueden descubrir cómo podrían hacer eso. Así que imagina que tienes el AST. ¿Qué harías? ¿Dónde harías cambios? Les daré unos cinco minutos para que lo intenten y luego volveré a las 16:16, 16:18. Y siéntanse libres de discutir juntos. Pongan sus ideas en el chat, cosas así. Muy bien, esto es bastante complicado ahora y no es muy obvio. Creo que una de las partes difíciles de esto es que un AST es como un nuevo lenguaje en sí mismo. Así que definitivamente puede ser difícil de entender. Entonces, la forma en que abordaría esto si fuera completamente nuevo en esto sería hacer clic en el nombre del tema y ver qué me muestra. Y verás aquí que tenemos algo que se llama nombre. Así que tenemos tipo nombre y mira arriba de eso. Tenemos tipo campo y luego eso está rodeado por otro campo. Así que vamos allí y esto es tipo campo y tiene un nombre ID. Así que ves cómo esto es en realidad lo que llamamos un campo con un nombre ID. Y esto también es un campo con un nombre tipo nombre.

17. Añadiendo Nombre de Tipo a Conjuntos de Selección

Short description:

Necesitamos verificar si existe un nombre de tipo en los nodos de campo de nuestras consultas. Esto asegura que el nombre de tipo sea visible cuando se devuelve la mutación o consulta. En GraphQL, los campos existen dentro de un conjunto de selección, que es un grupo de campos. Necesitamos encontrar estos conjuntos de selección y agregar los campos de nombre de tipo a ellos. Para lograr esto, podemos usar una función visitante para iterar a través del AST e identificar los conjuntos de selección. Al agregar los campos de nombre de tipo al arreglo de selecciones dentro del conjunto de selección, podemos lograr nuestro objetivo.

El truco es lo que queremos hacer es recorrer nuestras consultas y en cualquier lugar donde veamos un grupo de nodos de campo, queremos verificar si existe un nombre de tipo. Y si no existe, entonces queremos agregarlo. Y eso asegurará que cuando la mutación o consulta regrese podamos ver el nombre de tipo.

Ahora, para hacer eso, necesitamos saber dónde existen los campos. Y lo afortunado de GraphQL es que solo hay un lugar donde un campo puede existir y está dentro de algo llamado conjunto de selección. Entonces, cada vez que veas algo como esto en GraphQL donde es una... Algo así como una sintaxis de objeto con campos. Todo esto aquí se llama conjunto de selección. Y dentro de él hay selecciones que casi siempre son campos. Si tienes un fragmento, por ejemplo, como mi fragmento, entonces no es un campo. En cambio, se llama fragmento expandido. Pero en su mayor parte, puedes asumir que, ya sabes, en un conjunto de selección, tenemos un grupo de campos.

Entonces, eso es muy fácil en el sentido de que, okay, solo miramos un conjunto de selección y agregamos los campos. Pero lo más complicado es que necesitamos encontrar esos conjuntos de selección, ¿verdad? Así que, imagina que tenemos el conjunto de selección. Oh, sí, solo vamos a las selecciones, buscamos un campo con nombre de tipo y luego lo agregamos si es necesario. Entonces, eso parece bastante sencillo. Pero lo más complicado es, oh, bueno, ¿dónde están los conjuntos de selección? ¿Cómo los encontramos? Y como puedes ver, tenemos, por ejemplo, aquí, tenemos un conjunto de selección con un conjunto de selección dentro de él, lo cual se vuelve realmente complicado. Afortunadamente, hay una solución para esto, que es una cosa llamada función visitante.

Siéntete libre de seguir. Tenemos una pequeña, no ahí, tenemos una pequeña carpeta de utilidades aquí y un archivo GraphQL.ts aquí. Y lo que vamos a hacer es, simplemente vamos a crear una nueva función aquí llamada agregar nombre de tipo a conjuntos de selección. Un nombre bastante largo, lo siento, pero espero que describa lo que está sucediendo. Y tomaremos un nodo de documento y devolveremos uno. De acuerdo, genial.

18. Utilizando la Función Visitante para Simplificar la Iteración del AST

Short description:

Podemos simplificar el proceso utilizando una función visitante llamada 'visit' que itera a través del AST por nosotros. Nos permite enfocarnos en nodos específicos, como conjuntos de selección y campos, sin tener que iterar manualmente a través de todas las definiciones. Esto hace que nuestro código sea más conciso y eficiente.

Entonces, lo que vamos a hacer es que tenemos esta consulta y podríamos, al 100%, podríamos hacer query.puntos definiciones.para cada uno, y luego comenzar a iterar a través de todas las definiciones y todas las cosas y todo eso. Pero eso es mucho trabajo. Así que en su lugar, lo que vamos a hacer, vamos a ir aquí arriba a nuestra importación, vamos a agregar visit, ¿de acuerdo? Y se llama una función visitante. Si escuchas a alguien referirse a un visitante cuando están hablando de AST, no específicamente, GraphQL, típicamente, o se aplica a la mayoría de los AST para esto. Una función visitante, lo que hace es que recorre el AST por nosotros. Y luego, todo lo que hacemos es decir, como, oye, recorre todo el AST, haz todo el trabajo, y solo avísame cuando haya un conjunto de selección o cuando haya un campo o algo así.

19. Añadiendo el Nombre del Tipo a los Conjuntos de Selección

Short description:

Queremos agregar un campo, como el campo de ejemplo del nombre del tipo, al array de selecciones dentro de un conjunto de selección. Podemos utilizar la función visit para iterar a través del documento y llamar a una función cada vez que se encuentre un nodo de conjunto de selección. En este caso, la función registra el nodo en la consola. Después de ejecutar la prueba, podemos ver que los registros de la consola muestran los conjuntos de selección. Al verificar si existe un campo con el nombre nombre del tipo en el conjunto de selección, podemos devolver el mismo nodo y agregar el campo del nombre del tipo. Esto asegura que las selecciones no se cambien y obtenemos la misma consulta de vuelta.

Entonces, si volvemos aquí, lo que queremos cambiar es agregar un campo a, queremos agregar un campo, como este campo de ejemplo del nombre del tipo, al array de selecciones dentro de un conjunto de selección, ¿de acuerdo? Entonces, el nodo aquí es un conjunto de selección, y luego, dentro de él, tiene un atributo selecciones, que contiene campos. Entonces, lo que podemos hacer es llamar a visit, llamar a visit, y pasarle nuestro documento. Y ahora, cuando se ejecute esto, va a recorrer todo el documento e iterar a través de todo. Luego, lo que vamos a hacer es darle un objeto, y vamos a decir conjunto de selección, y simplemente le daremos una función. Y, por nuestra parte, podemos simplemente eliminar estos corchetes. Entonces tenemos conjunto de selección, y hagamos simplemente un registro en la consola. Nodo. Entonces, ¿qué crees que va a suceder? Así que pasamos todo esto a la consulta, y luego decimos, ¿cuándo es el conjunto de selección? O decimos, aquí hay un objeto para un conjunto de selección con una función que toma el nodo y devuelve, e imprime un registro en la consola. Entonces, ¿qué crees que va a suceder? ¿Alguna idea en el chat? De acuerdo. De acuerdo, no hay problema. Entonces, lo que va a hacer es llamar a esa función cada vez que encuentre un nodo de conjunto de selección. De hecho, voy a, He escrito algunas pruebas para que las utilicen. Así que vean el primer describe en la línea cinco, simplemente eliminen el skip. Y deténganse por ahora si quieren, y hagamos simplemente un MPN run test. De hecho, también vamos a verlo para que, ups. Genial, así que espero que la prueba falle, pero también espero, Espera un momento. Mi error. Asegurémonos de llamar a esto cuando, tenemos la función de consulta normalizada, no necesitamos preocuparnos por esto por ahora. Asegurémonos de que básicamente se convierta en esto, agregar nombre del tipo a los conjuntos de selección por ahora. Entonces tenemos consulta normalizada, toma una consulta, y luego devuelve una llamada a la función que agrega nombres de tipo a los conjuntos de selección aquí. Y si ejecutamos esto ahora, aquí vamos, tenemos algunos registros en la consola. Verás que los registros en la consola son conjuntos de selección. Entonces, si copiáramos esto en, en el analizador AST, deberíamos tener un conjunto de selección con el campo ID y el campo usuario, y luego se nos llamará nuevamente con un conjunto de selección con ID, nombre y dirección. Y debería ser llamado por tercera vez con un conjunto de selección con ID unidad. Y eso es básicamente lo que está sucediendo es que deberíamos ver tres llamadas, una, dos, tres. Así que eso es genial. Esa es la forma rápida y sucia de obtener todos esos conjuntos de selección. Pero obviamente esto no es suficiente. No solo queremos imprimir en la consola, queremos agregar un nombre de tipo. Entonces lo primero que podemos hacer en TypeScript hace esto mucho más fácil. Decimos, si nodes.selections.find. Supongo que tenemos un find, eso está bien. Entonces vamos a recorrer las selecciones. Vamos a decir si n.kind es igual a un campo y vamos a hacer kind.field. Entonces verificamos. Vamos a recorrer todas las entidades en la selección. Por ejemplo, aquí, el primero sería un campo, el segundo sería un campo, el tercero sería un campo. Entonces lo que vamos a hacer es, primero vamos a verificar si es un campo y luego vamos a verificar si tiene el nombre nombre del tipo. Entonces hacemos n.name.value es igual a nombre del tipo. Y vamos a ver si tenemos alguno de esos. No sé por qué estamos, oh, tenemos algunos. Aquí vamos. Eso es mejor. Genial. Así que tenemos una pequeña condición y simplemente decimos, si está, si en el conjunto de selección, en las selecciones, tenemos un campo y su valor, su nombre es nombre del tipo, entonces simplemente vamos a devolver el nodo. Y lo que esto hará es que significa que cuando se llame a la función de selecciones, nos devuelve el mismo nodo, y luego simplemente no se cambiará. Obtenemos la misma consulta de vuelta. ¿Tiene sentido, gente? Imprimiré dos veces en una sala. Voy a reproducirlo. Sí, estás en el punto Rodrigo.

20. Manipulando AST e Interceptando Solicitudes

Short description:

Analizamos la consulta en una sintaxis AST y manipulamos el AST agregando un campo de nombre de tipo a todas las selecciones. Esto nos da una nueva consulta con nombres de tipo. Estamos interceptando la solicitud y agregando los campos de nombre de tipo a la consulta. Ejecutamos la función de utilidad en nuestra consulta para cambiarla y la pasamos como segundo argumento a su controlador.

¿Alguna idea? Solo un momento. De acuerdo, bueno, todos ustedes dijeron que esto es fácil, así que seguiré adelante. Pero deténganme si tienen alguna pregunta. Esto definitivamente no es algo simple, así que no se preocupen por eso.

No queremos agregar un segundo nombre de tipo, por eso retornamos temprano en el conjunto de selección que ya lo tiene. Si no hay una selección con nombre de tipo, esto es lo que hacemos. Entonces, retornamos ese nodo. Las selecciones seguirán siendo las mismas. Queremos mantener todas las selecciones que ya estaban en ella. No queremos eliminar ID, nombre o algo así. Queremos mantener esas selecciones. Pero vamos a agregar una nueva. Y la nueva que vamos a agregar es, si solo hago clic en nombre de tipo aquí, es esto. Entonces, será un campo de tipo campo con un nodo de nombre, que es nombre de tipo, valor nombre de tipo. Hacemos kind, que es kind dot field. Luego, nombre, kind es kind dot name. Y si te preguntas por qué el nombre necesita tener, como un tipo también, es solo porque el nombre también es un tipo de nodo. Al igual que selecciones, conjunto de selección, cosas así, y el valor, nombre de tipo. Genial.

Y ahora verán que tenemos esta prueba funcionando. Entonces, si echamos un vistazo rápido a esta prueba, lo pondré en el chat para que todos estén al tanto. Y también lo subiré al repositorio. Pero, lo que hace esta prueba, es pasar una consulta sin nombres de tipo. Y luego nos aseguramos de que cada campo, cada conjunto de selección tenga un nombre de tipo. Y lo genial es que, en realidad, si tenemos una función de paso, que toma una cadena y la convierte en un AST, si imprimimos y decimos, así que veamos cómo se ve la nueva consulta de GraphQL después de llamar a esa función, console log, y verán que ahora, boom, tenemos ID, ID de usuario, nombre, dirección, pero ahora todos los conjuntos de selección tienen un nuevo campo nombre de tipo. Entonces, lo que acabamos de hacer es, en lugar de hacer una expresión regular complicada que recorre y hace todas estas cosas complicadas, en su lugar, hemos analizado la consulta en una sintaxis AST. Hemos manipulado el AST agregando un campo de nombre de tipo a todas las selecciones, y luego lo hemos devuelto, lo que nos da esta nueva consulta con todos estos nombres de tipo. Entonces, solo voy a, vamos a ver. De acuerdo. Genial. Bien. Eso está en la rama de progreso. De acuerdo, en una escala del uno al diez, ¿qué tan claro está hasta ahora para las personas? Ahí vamos. Entonces tenemos nombres de tipo en todas nuestras consultas, y la razón por la que lo mantuvimos separado es porque queremos usarlo durante la normalización de la consulta, pero también la normalización de la consulta, la idea es que convertimos una consulta de algo que es dinámico donde tal vez tiene diferentes nombres de consulta, los campos están ordenados de diferentes maneras, y simplemente tratamos de normalizarlo para que cada consulta que obtiene los mismos data tenga la misma representación, lo que luego facilita mucho la creación de una clave para la caché, porque imagina si tienes una, imagina que tienes una consulta que se ve así, y luego tienes una consulta que se ve así, queremos que ambas se almacenen en caché, queremos que la primera vaya a la caché, y luego la segunda sea un acierto de caché, aunque el orden sea diferente, es básicamente la misma consulta. Entonces, por eso tenemos una función de normalización, tal vez haga un archivo de lectura para cualquiera que quiera probar eso después de la masterclass, pero en fin, entonces tienes add type, mean, selection sets. Entonces lo que vamos a hacer es en nuestra solicitud aquí, vamos a echar un vistazo. Vamos a tomar el cuerpo en nuestros controladores de mutación, solo para no tener que intentar extraerlo nuevamente, y pasarlo junto con el documento, y luego lo que vamos a hacer es en esto, cuando reenviamos la mutación de GraphQL, vamos a incluir la solicitud, y luego vamos a hacer body es, déjame verificar esto, verifiquemos triplemente, algo así. De acuerdo. Genial. Entonces vamos a actualizar, oopsie. Genial. Entonces vamos a hacer la solicitud, también vamos a incluir el cuerpo, y vamos a hacer el cuerpo original. Entonces, imagina el JSON que se pasó originalmente, pero en su lugar, lo que vamos a hacer es agregar esos campos de nombre de tipo a la consulta. Entonces, para hacer eso, vamos a tomar esa función de utilidad que hicimos antes, agregar ejemplo de tiempo en conjuntos de selección, y vamos a envolver nuestra consulta en eso. Entonces lo que va a suceder ahora es, una vez que tengamos la importación para eso, genial. Entonces vamos a ejecutar esa función en nuestra consulta, para cambiar la consulta e incluir nombres de tipo, y luego la vamos a pasar en el cuerpo. Entonces ahora, en lugar de, ya sabes, simplemente enviar una, simplemente reenviar la solicitud, en realidad la estamos interceptando un poco. Y enviaré esto al chat. Solo asegúrate de pasar ese cuerpo como segundo argumento a tu controlador.

21. Manipulando Respuesta y Caché

Short description:

Una vez que hayas hecho eso, deberías poder hacer una mutación y verificar que la respuesta de la mutación contenga un campo de nombre de tipo. Vamos a hacer lo mismo para la consulta, pero con algunas diferencias. La parte complicada es asegurarnos de que no obtengamos un acierto de caché. Deshabilitar la caché es una buena idea. Vamos a recorrer la respuesta, obtener todos los nombres de tipo, escribirlos en la caché y crear una clave que indique qué consultas dependen de estos nombres de tipo. Cuando obtengamos una mutación, encontraremos todas las consultas que dependen del tipo de usuario y las invalidaremos.

Y una vez que hayas hecho eso, deberías poder hacer una mutación y verificar que ahora contiene un campo de nombre de tipo en la respuesta de la mutación. Así que para mí, simplemente voy a hacer esta mutación rápida aquí. Y boom, ahora obtengo 'crear usuario' con el nombre de tipo incluido. Y luego puedo cambiar eso, esa mutación en particular a una variable diferente. Y puedes verlo aquí. Muy bien, así que simplemente lo ejecutaré, y luego podrás ver esa especie de mutación ahora así es como llamarías a tu mutación, a la derecha, la estructura de código. Entonces puedes ver, este data se etiqueta inicialmente como 'alga'. Y lo que eso hace es que puedo compartir rápidamente mi pantalla, puedes ver aquí que ahora cuando hago mi mutación, obtengo un nombre de tipo de vuelta, lo cual es genial. Entonces, para nosotros, eso significa que ahora conocemos el tipo de data que ha sido manipulado por una mutación. Entonces, en teoría, podríamos comenzar a invalidar la caché, y casi estamos allí. Pero una última cosa que debemos hacer es básicamente lo mismo nuevamente, pero para la consulta. Y cuando, aquí, cuando reenviamos nuestra consulta, vamos a hacer básicamente el mismo tipo de cosas. Entonces vamos a hacer una solicitud de retorno. Nuestro cuerpo va a ser, de hecho, vamos a copiar y pegar. Y en lugar de agregar 'tap means a selection steps', lo llamaremos 'consulta normalizada'. La razón principal es que, en una mutación, lo único que realmente quieres manipular es agregar nombres de tipo. Mientras que en una consulta, hay muchas cosas que podrías querer hacer más adelante. Así que solo ordenar claves y cosas así. Entonces vamos a tener una llamada de función separada para eso, solo para asegurarnos de que a medida que hacemos cambios más adelante, no terminemos cambiando mutaciones de formas que no queremos. Y sí. Poner eso en el chat. Pero entiendes la idea general. Entonces, la parte complicada ahora es asegurarnos de que no obtengamos un acierto de caché. Pero si hago esto, oh, agregué un nombre de tipo allí. No debería haberlo tenido. Vamos a deshacernos de eso. Bien, entonces no veo el nombre de tipo, lo que significa que falta algo. E importar consulta normalizada. Y eso no fue un acierto de caché, ¿verdad? No. Crear consulta normalizada. Oh, ¿sabes qué? Ni siquiera guardé, ese probablemente sea el problema. Espera a que se construya y prueba eso de nuevo. Construcción completada, genial. Muy bien, voy a probar esto con, agreguemos más espacios. Solo para asegurarnos de que, eso fue un acierto de caché porque estamos eliminando espacios. Así que simplemente cambiamos el orden en su lugar. Genial, muy bien. Deshabilitar la caché es una muy buena idea, Rodrigo. Y básicamente, cuando estaba haciendo esto la última vez, solo quería borrar rápidamente la caché y no pude encontrar una forma realmente limpia de hacerlo. Pero sí, ahora tienes razón. Probablemente debería comentar esto por ahora. Esa es una idea mucho más inteligente. Sí. Así que hacemos eso ahora. Deberías ver que obtienes un nombre de tipo de vuelta con 'usuario'. Entonces, una última cosa que vamos a hacer, o dos últimas cosas. Así que los dos siguientes pasos, así que probablemente deberíamos terminar a tiempo. El primer paso es que vamos a recorrer toda esta respuesta y obtener todos los nombres de tipo y luego escribirlos en la caché. Por ejemplo, si esto devuelve un usuario en la organización, queremos almacenar esa información y luego crear una clave en la caché que diga, hey, esta consulta depende de estos nombres de tipo. Y luego lo que tenemos que hacer es cuando obtengamos una mutación, vamos a encontrar todas las consultas que dependen del tipo de usuario si hay respuestas de usuario e invalidarlas.

22. Acelerando y Extrayendo Nombres de Tipo

Short description:

Vamos a acelerar las cosas. Deberías tener un KBstore con respuestas, ID, ID de vista previa y nombres de tipo. Reinicia wrangler para usar el espacio de nombres de nombres de tipo. Escribe un nuevo JSON en la caché y extrae los atributos de nombre de tipo de la respuesta. Pruébalo y experimenta con ello.

Voy a intentar acelerar un poco las cosas para que podamos avanzar. Deberías tener, solo, Estoy seguro de que tengo dos ahí. Deberías tener un KBstore que se vea así. Tenemos respuestas, ID, ID de vista previa. Y si simplemente creo uno nuevo llamado nombres de tipo. Sí, genial. Voy a pegarlo aquí. Agrego una coma y, como hicimos antes, copio esto, agrego una coma y lo cambio a ID de vista previa. Y ahora tenemos un espacio de nombres llamado nombres de tipo, que luego podemos usar para ordenar los nombres por separado. En teoría, podrías ordenarlos en el mismo lugar que las respuestas si quieres, solo para asegurarte de que tienes una forma de evitar la superposición entre carreras y nombres de tipo. Esto es solo una forma clara de distinguirlos. Bien, si reinicio wrangler ahora, cuando haga env.typeNames.get o lo que sea, irá a este KB. Entonces, lo que voy a hacer es... Cuando obtengamos un nuevo JSON, lo escribiremos en la caché. Pero también, lo que haremos es obtener todos los atributos de nombre de tipo de la respuesta, lo cual iba a ser uno de los desafíos, pero no creo que tengamos tiempo. Así que pondré algunas cosas nuevas para que lo pruebes, la respuesta en el chat, pero definitivamente puedes, te recomendaría que lo pruebes, juegues con ello, y luego lo pruebes tú mismo. Y ve si puedes...

23. Caching Subscriptions in GraphQL

Short description:

¿Todavía se puede cachear la suscripción también? Las suscripciones generalmente no se cachéan ya que involucran datos y eventos en vivo. La caché de eventos se puede realizar en el punto final de GraphQL utilizando colas de seguridad o colas de mensajes no entregados. En nuestro caso, solo cachéamos consultas y mutaciones.

De acuerdo, aquí vamos. Aquí vamos. Una pequeña pregunta, ¿todavía se puede cachear la suscripción también? Las suscripciones, supongo que te refieres a una suscripción de GraphQL. No lo haríamos para esto. Básicamente, porque sí, esperaríamos que las suscripciones sean datos en vivo, que es impulsado por eventos. Probablemente no cachearíamos eventos, pero sí, si tienes una situación en la que, por ejemplo, necesitas enviar una suscripción, pero luego también necesitas enviarla más tarde en caso de que se pierda o algo así, tendrías que hacerlo en tu punto final de GraphQL, algún tipo de cola de seguridad o cola de mensajes no entregados o algo así. Sí, en nuestro caso, solo son consultas y mutaciones. Pero me gusta mencionar las suscripciones. Definitivamente, las personas no las usan lo suficiente. Así que felicitaciones a Mark si estás usando suscripciones en tus proyectos, eso es increíble. Así que voy a poner esto aquí.

24. Extracción de Nombres de Tipo y Almacenamiento en Caché

Short description:

Creamos una función llamada extract type names que visita cada objeto dentro de un objeto y verifica si tiene un tipo revelado. Si lo tiene, lo almacenamos. Pegamos esta función en nuestra carpeta de utilidades y agregamos pruebas para asegurarnos de que funcione correctamente. Realizamos algunos ajustes en la configuración de TS para admitir conjuntos y versiones más nuevas de JavaScript. Luego, en nuestra respuesta, llamamos a la función extract type names y almacenamos los nombres de tipo y las cadenas de consulta. Usamos context.waitUntil para asegurarnos de que ciertas promesas se completen antes de que el worker se apague.

Puedes pensar en esto como una función de visita. Simplemente recorremos el objeto y visitamos cada objeto dentro del objeto y preguntamos si tiene un tipo revelado. Si lo tiene, entonces lo devolvemos y lo almacenamos. Si no lo tiene, seguimos recorriendo los objetos hasta que finalmente obtenemos todos los atributos de nombre de tipo. Así que estoy bien con eso.

Peguemos eso en nuestra carpeta de utilidades. Y por ahora, como dije, he agregado algunas pruebas. Si quieres esperar, si quieres intentar hacer esto tú mismo, simplemente elimina esto e intenta hacerlo tú mismo. Y hay algunas pruebas que fallarán inicialmente. Y puedes intentar satisfacer todos los criterios. Veamos los conjuntos. Sí, está bien, es posible que necesites agregar. Está bien, es posible que necesites agregar esto a tu configuración de TS. Genial, para que tengamos soporte para conjuntos. Ahí vamos. ¿Y cómo me perdí esto? ¿De hecho? Sí, no tengo idea de por qué esto nunca realmente sería pero ES2017, bien, así que también lo agregaremos. Genial. No tanto. ¿Sabes qué? Está bien, hagámoslo mucho más fácil. Simplemente cambiemos esto a ESNext. Creo que eso debería cubrir todo. Sí, está bien. No estoy seguro de que funcione, pero lo veremos cuando lleguemos allí. De acuerdo, solo quieres agregar, oh sí, eso funciona. Solo agrega esto. Básicamente esto agrega TypeScript por defecto, el compilador asumirá que estás polifilando o transpilando características del lenguaje de versiones más nuevas de JavaScript. Cosas como los valores de objeto, conjuntos, cosas de esa naturaleza en todas las versiones de Node. Así que simplemente vamos a proporcionar un poco para decirle a TypeScript, oye, estamos usando algunas características avanzadas de JavaScript, que normalmente están disponibles, pero en este caso, sí. Genial. Tenemos nuestra función extract type names.

Y nos quedan solo unos minutos. Y lo que vamos a hacer es en nuestra respuesta, si es un error, lo ignoramos. Oh no. Si no es un error, lo siento. Lo que vamos a hacer es llamar a extract type names. Asegurémonos de importarlo también. Asegúrate de tenerlo en tus herramientas. Y le daremos nuestro nuevo JSON. Y eso nos dará un array. Y luego, para cada uno de ellos, vamos a recorrer los nombres de tipo y vamos a hacer m.typeNames.put el nombre de tipo. Y luego vamos a poner la cadena de consulta. Y lo que podemos hacer es, hay una pequeña cosa genial que no obtienes en Lambda, desafortunadamente. Pero context.waitUntil te permite decir, como, hey, aquí hay una promesa. No la esperaré ahora, pero no apagues el worker hasta que esta promesa se cumpla. Lo cual es bastante genial porque significa que, significa que podemos hacer cosas como esta, darle un montón de promesas para resolver. Y, genial. Así que solo le damos dos cosas que hacer. Y solo decimos, como, asegúrate de que esta promesa esté completa antes de apagar el entorno. Decimos, escribir la respuesta en la caché y también para cada nombre de tipo, almacenar en nuestros nombres de tipo, el nombre de tipo y luego, ooh, espera. Me perdí algo ahí. Espera un momento.

25. Caching and Storing Queries

Short description:

Vamos a intentarlo de nuevo. Vamos a utilizar una caché y comenzar con type names.get para nuestro nombre de tipo. Obtendremos los nombres de tipo, si no hay ninguno, utilizaremos un array vacío y luego tomaremos el array anterior del almacenamiento y agregaremos nuestra consulta. Envolveremos promise.all con un montón de promesas, escribiendo cosas en la caché y obteniendo la colección existente de consultas para cada nombre de tipo. Pondremos esto en el chat y devolveremos la promesa desde el puerto. Cada vez que obtengamos una respuesta, la escribiremos en la caché y en una lista para ese nombre de tipo. Agregaré una entrada en el archivo readme del repositorio para el último paso. Siéntete libre de hacer preguntas en el repositorio o en Discord.

Vamos a intentarlo de nuevo. Y, mencioné anteriormente, pero hay formas mucho más avanzadas de hacer esto. Y, es mucho para repasar. Así que, ten eso en cuenta. Pero, lo que vamos a hacer es, vamos a utilizar una caché y comenzar con type names.get para nuestro nombre de tipo. Entonces, nuestros nombres de tipo, solo para ayudarte, se verán algo así. Vamos a tener una clave, que podría ser como usuario. Y, el valor será un objeto con tal vez una consulta, un id, y luego podríamos tener otra consulta con, no sé, usuarios o lo que sea. Y, vamos a tener eso para cada nombre de tipo.

Entonces, vamos a verificar el chat, a ver si todos están bien. Sí. Entonces, vamos a obtener los nombres de tipo. Pasar eso, y simplemente utilizaremos un array vacío si no hay nombres de tipo. Y luego lo que vamos a hacer es tomar ese array anterior que estaba en el almacenamiento, y luego también agregar nuestra consulta. Y luego esto dejará de quejarse. Y, por eso vamos a convertir esto en una cadena. Sí, estoy bastante seguro de que Cloudflare y solo al convertir esto en una cadena, esto podría estar mal, pero está bien.

Muy bien, es un poco complicado, pero espero que. Mantengámoslo así por ahora. Espero que esto tenga sentido. Estamos diciendo, espera hasta que esta promesa se cumpla. Y luego la promesa que estamos haciendo es envolver promise.all con un montón de promesas. Entonces, la primera es escribir las cosas en la caché. Y la segunda es, oh, asegurémonos de que esto sea asíncrono. Para cada nombre de tipo, obtenemos la colección existente de consultas para ese nombre de tipo. Y luego agregamos onEvil aquí. Y luego veamos dónde nos falta algo. Oh. Creo que tenemos uno de más. Ahí vamos. Genial. Muy bien. Se supone que se va a construir para mí. No. ISL. Se esperaba una coma en la posición 66. Creo que nos falta uno aquí. Podemos simplemente... De acuerdo. Genial. Voy a poner esto en el chat, y creo que... ¿No deberíamos devolver la promesa desde el puerto? Acabo de agregar un wait. Hagámoslo más simple como dijiste. Sí, sigue. Devolvamos la promesa. Increíble. Entonces, lo que sucederá es que, cada vez que obtengamos una respuesta, la escribiremos en la caché y también escribiremos la respuesta en una lista para ese nombre de tipo. Lo que haré es agregar una pequeña entrada en el archivo readme o algo así en el repositorio con el último paso. Y luego, si alguien tiene algún problema o si quieres probar el último paso, siéntete libre de dejar los problemas abiertos en el repositorio.

26. Manejo de Mutaciones e Invalidación de Consultas

Short description:

El último paso es manejar las mutaciones de la misma manera que las consultas. En lugar de almacenar los nombres de tipo, recuperamos las consultas asociadas con los nombres de tipo devueltos por la mutación. Eliminamos todas estas consultas, asegurándonos de que cuando hagamos una solicitud posterior, las consultas invalidadas no se utilicen. Este enfoque es similar a cómo Urql maneja las consultas y mutaciones de forma predeterminada. A diferencia de Apollo, no es necesario volver a buscar manualmente las consultas. Siempre que las mutaciones devuelvan los datos actualizados, Urql se encarga de invalidar las consultas relevantes. Pasemos a Async.

Si tienes alguna pregunta, puedes hacerla allí o en Discord. Pero el último paso será hacer exactamente lo mismo con las mutaciones, donde obtenemos los nombres de tipo de la mutación. La única diferencia ahora es que en lugar de almacenarlos, lo que haremos es ir a nuestro almacenamiento de nombres de tipo, obtendremos todas las consultas para los nombres de tipo que se han devuelto. Por ejemplo, si la mutación devuelve el nombre de tipo `usuario`, obtendremos todas las consultas que devuelvan `usuario` como uno de los nombres de tipo en la respuesta. Y luego las eliminaremos todas. Y haremos eso para cada nombre de tipo que coincida en la mutación. Y en teoría, eso significa que cuando hagamos una llamada para obtener usuarios y hagamos algo para eliminar un usuario o cambiar un usuario, y luego hagamos la llamada para obtener usuarios nuevamente, sabremos con certeza que la consulta será invalidada y todas las consultas que usen usuarios también serán invalidadas y podremos obtener una copia actualizada. Y eso es en realidad cómo funciona Urql de forma predeterminada. Es bastante ingenuo, pero es realmente genial porque significa que, en comparación con Apollo, donde podrías tener que llamar a algo como refetch queries, no se ha utilizado en un tiempo. Pero con Urql, básicamente puedes hacer un montón de consultas y mutaciones. Siempre que tus mutaciones devuelvan los datos que han cambiado, no tienes que preocuparte por volver a buscar consultas. Funciona para ti. Pero tengo mis preferencias. Eso es básicamente todo. Como dije, podemos continuar con Async. Pondré información en el repositorio.

Watch more workshops on topic

GraphQL Galaxy 2021GraphQL Galaxy 2021
140 min
Build with SvelteKit and GraphQL
Top Content
Featured WorkshopFree
Have you ever thought about building something that doesn't require a lot of boilerplate with a tiny bundle size? In this workshop, Scott Spence will go from hello world to covering routing and using endpoints in SvelteKit. You'll set up a backend GraphQL API then use GraphQL queries with SvelteKit to display the GraphQL API data. You'll build a fast secure project that uses SvelteKit's features, then deploy it as a fully static site. This course is for the Svelte curious who haven't had extensive experience with SvelteKit and want a deeper understanding of how to use it in practical applications.

Table of contents:
- Kick-off and Svelte introduction
- Initialise frontend project
- Tour of the SvelteKit skeleton project
- Configure backend project
- Query Data with GraphQL
- Fetching data to the frontend with GraphQL
- Styling
- Svelte directives
- Routing in SvelteKit
- Endpoints in SvelteKit
- Deploying to Netlify
- Navigation
- Mutations in GraphCMS
- Sending GraphQL Mutations via SvelteKit
- Q&A
React Advanced Conference 2022React Advanced Conference 2022
95 min
End-To-End Type Safety with React, GraphQL & Prisma
Featured WorkshopFree
In this workshop, you will get a first-hand look at what end-to-end type safety is and why it is important. To accomplish this, you’ll be building a GraphQL API using modern, relevant tools which will be consumed by a React client.
Prerequisites: - Node.js installed on your machine (12.2.X / 14.X)- It is recommended (but not required) to use VS Code for the practical tasks- An IDE installed (VSCode recommended)- (Good to have)*A basic understanding of Node.js, React, and TypeScript
GraphQL Galaxy 2022GraphQL Galaxy 2022
112 min
GraphQL for React Developers
Featured Workshop
There are many advantages to using GraphQL as a datasource for frontend development, compared to REST APIs. We developers in example need to write a lot of imperative code to retrieve data to display in our applications and handle state. With GraphQL you cannot only decrease the amount of code needed around data fetching and state-management you'll also get increased flexibility, better performance and most of all an improved developer experience. In this workshop you'll learn how GraphQL can improve your work as a frontend developer and how to handle GraphQL in your frontend React application.
React Summit 2022React Summit 2022
173 min
Build a Headless WordPress App with Next.js and WPGraphQL
Top Content
WorkshopFree
In this workshop, you’ll learn how to build a Next.js app that uses Apollo Client to fetch data from a headless WordPress backend and use it to render the pages of your app. You’ll learn when you should consider a headless WordPress architecture, how to turn a WordPress backend into a GraphQL server, how to compose queries using the GraphiQL IDE, how to colocate GraphQL fragments with your components, and more.
GraphQL Galaxy 2020GraphQL Galaxy 2020
106 min
Relational Database Modeling for GraphQL
Top Content
WorkshopFree
In this workshop we'll dig deeper into data modeling. We'll start with a discussion about various database types and how they map to GraphQL. Once that groundwork is laid out, the focus will shift to specific types of databases and how to build data models that work best for GraphQL within various scenarios.
Table of contentsPart 1 - Hour 1      a. Relational Database Data Modeling      b. Comparing Relational and NoSQL Databases      c. GraphQL with the Database in mindPart 2 - Hour 2      a. Designing Relational Data Models      b. Relationship, Building MultijoinsTables      c. GraphQL & Relational Data Modeling Query Complexities
Prerequisites      a. Data modeling tool. The trainer will be using dbdiagram      b. Postgres, albeit no need to install this locally, as I'll be using a Postgres Dicker image, from Docker Hub for all examples      c. Hasura
GraphQL Galaxy 2021GraphQL Galaxy 2021
48 min
Building GraphQL APIs on top of Ethereum with The Graph
WorkshopFree
The Graph is an indexing protocol for querying networks like Ethereum, IPFS, and other blockchains. Anyone can build and publish open APIs, called subgraphs, making data easily accessible.

In this workshop you’ll learn how to build a subgraph that indexes NFT blockchain data from the Foundation smart contract. We’ll deploy the API, and learn how to perform queries to retrieve data using various types of data access patterns, implementing filters and sorting.

By the end of the workshop, you should understand how to build and deploy performant APIs to The Graph to index data from any smart contract deployed to Ethereum.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
From GraphQL Zero to GraphQL Hero with RedwoodJS
Top Content
We all love GraphQL, but it can be daunting to get a server up and running and keep your code organized, maintainable, and testable over the long term. No more! Come watch as I go from an empty directory to a fully fledged GraphQL API in minutes flat. Plus, see how easy it is to use and create directives to clean up your code even more. You're gonna love GraphQL even more once you make things Redwood Easy!
Vue.js London Live 2021Vue.js London Live 2021
24 min
Local State and Server Cache: Finding a Balance
Top Content
How many times did you implement the same flow in your application: check, if data is already fetched from the server, if yes - render the data, if not - fetch this data and then render it? I think I've done it more than ten times myself and I've seen the question about this flow more than fifty times. Unfortunately, our go-to state management library, Vuex, doesn't provide any solution for this.For GraphQL-based application, there was an alternative to use Apollo client that provided tools for working with the cache. But what if you use REST? Luckily, now we have a Vue alternative to a react-query library that provides a nice solution for working with server cache. In this talk, I will explain the distinction between local application state and local server cache and do some live coding to show how to work with the latter.
React Day Berlin 2022React Day Berlin 2022
29 min
Get rid of your API schemas with tRPC
Do you know we can replace API schemas with a lightweight and type-safe library? With tRPC you can easily replace GraphQL or REST with inferred shapes without schemas or code generation. In this talk we will understand the benefit of tRPC and how apply it in a NextJs application. If you want reduce your project complexity you can't miss this talk.
React Advanced Conference 2021React Advanced Conference 2021
36 min
Living on the Edge
React 18 introduces new APIs for rendering applications asynchronously on the server, enabling a simpler model for architecting and shipping user interfaces. When deployed on edge networking platforms like Cloudflare Workers, we can get dramatic performance and user experience improvements in our applications. In this talk, Sunil will demo and walk through this new model of writing React applications, with some insight into the implications for data fetching, styling, and overall direction of the React ecosystem.