Cómo Cachear en el Borde las APIs de GraphQL

Rate this content
Bookmark

Durante años, no poder cachear GraphQL se consideraba una de sus principales desventajas en comparación con las APIs RESTful. Ya no más. GraphCDN hace posible cachear casi cualquier API de GraphQL en el borde, y no solo eso, sino que nuestra caché es aún más inteligente que cualquier caché RESTful podría ser. Sumergámonos en los entresijos de GraphCDN para descubrir cómo exactamente logramos que esto suceda.

29 min
22 Oct, 2021

Video Summary and Transcription

El orador habla sobre su experiencia con el caché en el borde de las APIs de GraphQL, comenzando con las dificultades que enfrentaron con una mala elección de base de datos. Encontraron éxito con GraphQL, lo que ayudó a escalar sus servidores y llevó a una adquisición por parte de GitHub. El orador profundiza en la pieza clave que permite el caché de GraphQL, el metafield __typename. También abordan los desafíos del caché en el borde, incluyendo la autorización y la purga global de la caché. El orador comparte una historia de éxito con GraphCDN y menciona el desafío continuo de manejar la caché para listas con paginación.

Available in English

1. Introducción a la Caché en el Borde de las APIs de GraphQL

Short description:

Gracias por esa encantadora introducción. Estoy muy contento de estar de vuelta y emocionado de estar aquí hoy y hablarles sobre la caché en el borde de las APIs de GraphQL.

Gracias por esa encantadora introducción. Al igual que todos los oradores aquí y supongo que también todos ustedes, esto se siente absolutamente surrealista. Estar parado frente a personas reales, mirando sus rostros. Esto es increíble. Me encanta. Estoy muy contento de estar de vuelta y emocionado de estar aquí. Amo Londres. De hecho, conseguí mi primer trabajo aquí hace mucho tiempo. Solía vivir en Londres durante un par de meses e hice una pasantía aquí. Esta ciudad tiene un lugar especial en mi corazón y estoy muy emocionado de estar aquí hoy y hablarles sobre la caché en el borde de las APIs de GraphQL.

2. La historia de Spectrum y la base de datos en tiempo real

Short description:

Ya tuve una introducción muy encantadora, así que puedo omitir un poco de eso, pero si quieres seguirme en cualquier lugar de Internet, mi nombre de usuario es mxsdbr, que parece muy complicado pero en realidad es solo mi nombre sin las vocales. Así que solo toma mi nombre, quita las vocales y llegarás a mi nombre de usuario. Entonces, esta historia comienza en 2018. Yo era el CTO de una startup joven y en crecimiento llamada Spectrum. Y estábamos construyendo una especie de versión moderna de los foros comunitarios. Y por alguna razón incomprensible que no puedo recordar, elegí una base de datos realmente terrible que no mencionaré, porque no quiero avergonzar a nadie, pero es una base de datos muy pequeña que probablemente ninguno de ustedes haya usado, y se promocionaban como la Base de Datos en Tiempo Real.

Ya tuve una introducción muy encantadora, así que puedo omitir un poco de eso, pero si quieres seguirme en cualquier lugar de Internet, mi nombre de usuario es mxsdbr, que parece muy complicado pero en realidad es solo mi nombre sin las vocales. Así que solo toma mi nombre, quita las vocales y llegarás a mi nombre de usuario. Sé que desearía haber elegido algo diferente cuando era más joven y no sabía lo que estaba haciendo, pero así es como es ahora. No puedo cambiarlo más.

Entonces, esta historia comienza en 2018. Yo era el CTO de una startup joven y en crecimiento llamada Spectrum. Y estábamos construyendo una especie de versión moderna de los foros comunitarios. Así que construimos esta plataforma donde la mayoría de los proyectos de código abierto tenían a todos sus usuarios hablando entre sí. Informaban errores, hablaban entre ellos sobre cómo usar componentes de estilo en mi caso, pero también muchos otros proyectos de código abierto y muchos desarrolladores lo usaban. Y en realidad crecimos bastante rápido. Ahora, yo era el CTO de esa startup y no tenía idea de lo que estaba haciendo. Literalmente cero. Especialmente no una aplicación de chat público en tiempo real, que es un conjunto de problemas bastante interesante para resolver, porque estábamos tomando lo que eran los foros, donde puedes publicar publicaciones, publicar hilos y comentar debajo de ellos, y lo convertimos todo en tiempo real. Intentamos combinar lo mejor de lo que los foros de los años 2000 te ofrecen con lo que Slack y Discord te ofrecen hoy en día. Intentamos combinar lo mejor de ambos mundos. Y eso me trajo algunos problemas técnicos realmente interesantes, porque teníamos todo el tráfico de lectura pesada de un foro. Muchas, muchas personas venían a nuestra plataforma y leían todos los hilos y publicaciones y el contenido que la gente compartía, pero todo era en tiempo real. Así que todos se suscribían a una conexión WebSocket y transmitían actualizaciones en tiempo real mientras las personas conversaban entre sí.

Y por alguna razón incomprensible que no puedo recordar, elegí una base de datos realmente terrible que no mencionaré, porque no quiero avergonzar a nadie, pero es una base de datos muy pequeña que probablemente ninguno de ustedes haya usado, y se promocionaban como la Base de Datos en Tiempo Real. Y toda su idea era que podías tomar cualquier consulta de base de datos y agregarle una cosa al final y luego obtendrías una suscripción en tiempo real a cualquier cambio en esa consulta de base de datos. Vaya, eso suena increíble. Eso suena exactamente como lo que necesitamos. Estamos construyendo esta plataforma de chat en tiempo real. Seguramente eso es exactamente lo que necesitamos. Así que lo usamos, pero el problema era que estaba construido realmente mal. Y descubrí a posteriori que esta empresa que construyó la base de datos había recaudado dinero de inversores y no estaba creciendo muy rápido. No lograron obtener ninguna cuota de mercado en comparación con una MongoDB, ¿verdad? O incluso un Postgres o MySQL. Así que su idea era: `Ok, tenemos esta base de datos realmente genial. Vamos a hacerla en tiempo real. Y luego la vamos a vender`. Y pasaron medio año construyéndola, pero nunca la ejecutaron realmente en producción.

3. Struggles with Database and Success with GraphQL

Short description:

Y simplemente no escalaba. Nos encontramos con muchas limitaciones con esta cosa. Nuestros servidores se caían todos los días. Probamos muchas cosas diferentes. GraphQL funcionó extremadamente bien para nosotros. Fuimos adquiridos por GitHub y no tuvimos grandes filtraciones de seguridad.

Y simplemente no escalaba, ¿verdad? Nos encontramos con muchas limitaciones con esta cosa donde cientos de miles de usuarios usaban Spectrum todos los meses. Esta database ni siquiera podía manejar cien conexiones de actualización en tiempo real, literalmente. Así que estábamos luchando.

Ahora, si alguna vez has construido un backend de producción, sabes que cambiar tu database es realmente, realmente difícil. Sé que hay ORMs y cosas así, y deberíamos haber usado uno de esos, pero no lo hicimos porque esta database traía su propio ORM. Así que pensamos, eso es genial. Tenemos todo en uno, ¿verdad? Todo esto es increíble. Así que no podíamos cambiar fácilmente la database. Y recuerdo distintamente un período de tiempo muy específico a principios de 2018, como diciembre, enero, febrero. Nuestros servidores se caían todos los días. Literalmente. Dos o tres veces al día, nuestros servidores simplemente se caían y teníamos que reiniciarlos manualmente , lo creas o no, lo cual es absolutamente ridículo.

Para crear estas diapositivas, busqué en Google tiempo de inactividad del servidor, porque quería encontrar una foto de cómo se ve eso. Y por alguna razón, Google asocia esta imagen con el tiempo de inactividad del servidor. Si esto es lo que parece tu tiempo de inactividad del servidor, tienes problemas mucho más grandes porque todo tu centro de datos está en llamas. Espero que esto no sea lo que parecía nuestro tiempo de inactividad del servidor, porque simplemente se caía. Al menos no estaban en llamas. Pero de todos modos, teníamos esto, literalmente, dos o tres veces al día, estábamos colapsando nuestro servidor y nuestros servidores se caían, y me sentía increíblemente estresado. Porque yo era la persona técnica principal en ese equipo y era responsable de hacer que todo esto funcionara, y no podíamos descubrir cómo hacer que esta database funcionara para nosotros de la manera que necesitábamos. Y pasé meses probando muchas cosas diferentes. Probamos muchas configuraciones diferentes de database. Intentamos trabajar con sus desarrolladores principales. Nada funcionó.

Ahora, estábamos usando GraphQL, y GraphQL realmente es lo único que diría que nos funcionó extremadamente bien. Y GraphQL nos permitió construir una API muy rápidamente y hacer que funcionara realmente, realmente, realmente bien. Sorprendentemente bien, porque nunca habíamos usado GraphQL antes. De hecho, uno de mis momentos de mayor orgullo, y aclaración, pero uno de mis momentos de mayor orgullo fue cuando finalmente fuimos adquiridos por GitHub. GitHub contrató al grupo NCC, que es una de las mayores empresas de testing de seguridad en el planeta, pagaron a 11 de sus mejores personas para intentar hackear nuestros sistemas durante ocho días seguidos. Literalmente ocho días a tiempo completo, 11 de los mejores investigadores de seguridad intentaron hackear Spectrum, porque GitHub quería saber, si vamos a comprar esta empresa, ¿tendremos que lidiar con alguna filtración de database? Y todavía recuerdo, estaba súper asustado por eso y el momento de mayor orgullo de mi vida fue cuando recibí ese informe y el primer ítem decía: no se encontraron grandes filtraciones de seguridad. Y pensé, sí, lo hicimos muy bien.

4. Caching and GraphQL Clients

Short description:

No tengo idea de cómo lo hicimos, pero no tuvimos ninguna filtración de seguridad, ¿verdad? Estábamos usando GraphQL y estábamos muy contentos con ello. Empecé a investigar cómo los clientes de GraphQL hacen caché y eso es de lo que quiero hablar hoy. La pieza clave que hace posible la caché de GraphQL es el metacampo __typename.

No tengo idea de cómo lo hicimos, pero no tuvimos ninguna filtración de seguridad, ¿verdad? No teníamos ninguna política de seguridad ni nada, pero creo que en realidad, de alguna manera, la forma en que funciona GraphQL, donde cada resolutor individual te dice qué datos obtener y de dónde, simplemente agregamos un pequeño fragmento de control de acceso en cada resolutor y eso significaba que nadie podía acceder a los datos que no debían.

De todos modos, estábamos usando GraphQL y estábamos muy contentos con ello. Y en mi cabeza, después de un mes intentando solucionar nuestros problemas de la base de datos del servidor, pensé, vale, tenemos que encontrar una forma de reducir nuestro tráfico. Tenemos que encontrar una forma, sin tener menos usuarios, ¿verdad? Aún queremos más usuarios, pero queremos menos tráfico. ¿Cómo podemos lograrlo? Y por supuesto, la respuesta a eso es la caché. Y en mi cabeza pensé, vale, espera, tenemos esta cosa de foro público, ¿verdad?, como tenemos un foro público, muchas personas acceden a él sin autenticarse y simplemente leen las cosas, ese es el caso de uso ideal para la caché, ¿verdad? Solo quiero poner una caché delante de mi API de GraphQL, solo cachear todas las consultas y con suerte eso reduciría nuestro tráfico a un nivel en el que no nos estrellaríamos.

Mientras seguía pensando en esto, pensé, ¿por qué no puedo simplemente ejecutar un cliente de GraphQL en el borde, ¿verdad?, esa es realmente la pregunta que me estaba haciendo porque si alguna vez has usado un cliente de GraphQL o has oído hablar de uno como Apollo o Urql, eso es exactamente lo que hacen. Los clientes de GraphQL ofrecen una gran experiencia de usuario porque, en el navegador, ejecutan una caché de GraphQL y almacenan en caché todas las consultas que ven y las actualizan de forma muy inteligente, en acciones, y hacen un montón de cosas realmente inteligentes y eso hace que la experiencia sea realmente genial para el usuario. Así que en mi cabeza pensé, vale, los clientes de GraphQL hacen esto en el navegador, ¿por qué no puedo hacer esto en el servidor? Solo quiero lo mismo exacto, solo quiero tomar el cliente de Apollo y desplegarlo en el servidor, ¿verdad? ¿Por qué eso no puede funcionar? Y luego, incluso un paso más allá, si ya estoy haciendo caché, ¿por qué no puedo hacer caché cerca de mis usuarios en el borde, ¿verdad? Sunil acaba de hablar sobre CloudFlare y hay 250 ciudades en todo el mundo, ¿por qué no puedo simplemente poner una caché en cada uno de esos servidores y así no solo nos ahorraría un montón de tráfico, sino que también haría que la experiencia sea mucho más rápida para todos nuestros usuarios en todo el mundo. ¿Por qué no puedo hacer eso?

Así que empecé a investigar esto y empecé a leer sobre cómo los clientes de GraphQL hacen caché, y de eso quiero hablar un poco hoy. Si miras una consulta de GraphQL estándar como esta, hice este ejemplo, ¿verdad?, pero esta consulta de GraphQL obtiene una publicación de un blog según un cierto slug y obtiene su ID, título y del autor, también obtiene su ID, nombre y avatar. Y realmente, la única cosa clave que hace posible la caché de GraphQL es el metacampo __typename porque puedes agregarlo automáticamente a cualquier consulta de GraphQL. Y cuando agregas eso, la consulta de GraphQL termina viéndose así, ¿verdad? Tienes este campo mágico __typename en tu consulta de GraphQL. Ahora, no tienes que definir esto. Cada API de GraphQL lo admite porque está en la especificación. Cada tipo de objeto en tu API de GraphQL tiene que tener un campo __typename. ¿Qué hace ese campo? Bueno, si ejecutamos esta consulta y obtenemos los datos, lo que obtendríamos se vería un poco así. Es el dato de la publicación y también hay estos dos campos __typename que nos dicen que la publicación es del tipo POST, obvio, y el autor es del tipo USER. ¿OK, tiene sentido, verdad? Tenemos una publicación y un usuario. ¿Por qué ese campo de nombre de tipo es tan interesante? ¿Qué nos dice eso? Bueno, ahora podemos mirar esto y decir, ah, OK, puedo tomar todos estos datos, toda esta respuesta, ponerla en la caché y sé que esta respuesta contiene la publicación con el ID 5 y el usuario con el ID 1. ¿OK? Así que sabemos que esta respuesta que acabamos de poner en nuestra caché contiene la publicación con el ID 5 y el usuario con el ID 1. ¿Y qué? ¿Por qué necesitamos etiquetar nuestras respuestas en caché con algo? Bueno, aquí está la otra cosa interesante de GraphQL. Diferencia entre consultas y mutaciones. Y así, si tenemos una mutación como una mutación EDIT POST, donde decimos, OK, queremos cambiar el título de esta publicación de blog, de nuevo, podemos agregar el campo __typename a esta mutación. Y podemos decir, OK, de la mutación EDIT POST, solo avísame qué tipo obtengo de vuelta. Ahora, nosotros, como humanos, por supuesto, sabemos que EDIT POST probablemente, con suerte, devuelve una publicación. Sería un poco extraño si eso devolviera un usuario. Eso no tendría sentido. Pero la API también nos lo dice.

5. GraphQL Client Mutation and CachedQuery Linking

Short description:

Y también se lo dice al cliente de GraphQL. Ahora sabemos que se ejecutó una mutación en nuestra API. Y esa mutación cambió la publicación con el ID 5. Debido a que tenemos este metacampo __typename, podemos vincular las actualizaciones de mutación a los resultados de las consultas en caché. Esa es la magia que hace que la caché de GraphQL funcione para los clientes de GraphQL. Esta introspección, este metacampo __typename, te permite obtener la información de lo que incluso está en este fragmento JSON.

Y también se lo dice al cliente de GraphQL. Y lo que sucede es que cuando esta respuesta regresa de la mutación EDIT POST, cuando la ejecuto en mi origen, lo que recibo se ve un poco así, la publicación data con el título actualizado. OK. Pero ahora aquí está la clave. Ahora sabemos que se ejecutó una mutación en nuestra API. Y esa mutación cambió la publicación con el ID 5. Porque tenemos este metacampo __typename, podemos vincular las actualizaciones de mutación a los resultados de la consulta en caché. Y podemos decir, oh, mierda, acabamos de tener una mutación y la publicación con el ID 5 cambió. Eso significa que debo invalidar cualquier resultado de consulta en caché que contenga esa publicación con el ID 5. ¿Cómo encuentro esos? Bueno, afortunadamente, los etiqueté cuando los puse en la caché, ¿verdad? Tomamos esa respuesta. La pusimos en la caché. Y dijimos que esta respuesta contiene la publicación con el ID 5. Así que ahora, cuando una mutación pasa por nuestra caché, podemos ir y decir, oh, mira, sabemos que la publicación con el ID 5 ha cambiado. Y podemos invalidar cualquier resultado de consulta en caché que contenga esa publicación. Y esa es la magia que hace que la caché de GraphQL funcione para los clientes de GraphQL. Esa es realmente la pieza clave, esta introspección, este metacampo __typename que te permite simplemente obtener la información de lo que incluso está en este fragmento JSON, ¿verdad? Como, tengo esta enorme cantidad de data, ¿qué hay incluso en eso? Así que eso es increíble. Y funciona maravillosamente.

6. GraphQL Client Caching and ListInvalidations

Short description:

Desafortunadamente, la magia tiene un límite. ListInvalidations es donde termina la magia. El principal caso especial que los clientes de GraphQL te obligan a resolver manualmente es cuando una mutación cambia datos que aún no están incluidos en una consulta de lista. Los clientes de GraphQL ahora hacen algo aún más avanzado, con la caché a nivel de documento.

Desafortunadamente, la magia tiene un límite. Y el lugar donde termina es ListInvalidations. Porque si lo piensas, tenemos esta respuesta CachedQuery. Contiene la publicación con el ID 5 y el usuario con el ID 1. Ahora, supongamos que tenemos una consulta POST que es una lista de publicaciones, ¿verdad? Y aquí es donde ListInvalidation se vuelve un poco complicado. Porque esta lista nos devolverá la única publicación que tenemos ahora mismo. Nuevamente, la publicación con el ID 5 con un cierto título.

Ahora supongamos que tenemos una mutación llamada createPost. Y creamos una nueva publicación. Y luego, desde esa mutación, el origen nos devuelve la nueva publicación. Cuando miramos la respuesta data de eso, la respuesta data tiene un nombre de tipo POST y un ID de 6. Ahora sabemos, está bien, una mutación acaba de pasar por nuestra caché. Devolvió la publicación con el ID 6. Invalidemos cualquier resultado de CachedQuery que contenga la publicación con el ID 6. El problema es que nuestra lista aún no contiene la publicación con el ID 6. Porque, ¿cómo podría hacerlo? La publicación no existía cuando consultamos esa lista. Por lo tanto, no podemos invalidar automáticamente esa consulta. Y este es el principal caso especial que los clientes de GraphQL te obligan a resolver manualmente. Si alguna vez has usado GraphQL en el cliente, es muy probable que hayas tenido que hacer una validación manual de la caché para estos casos. Por ejemplo, con Urql, se ve un poco así. Básicamente, puedes decir, oye, si la mutación createPost pasa por la caché de Urql, entonces por favor invalida cualquier resultado de consulta en caché que contenga la consulta con una lista de publicaciones. Y de esa manera, puedo decir, OK, cuando la mutación createPost pasa por nosotros, invalidemos la lista de publicaciones porque sabemos que ha cambiado. Si se acaba de crear una publicación, probablemente esté en esa lista. Probablemente necesitemos invalidar cualquier consulta que contenga esa lista. Y así, hay un poco de trabajo manual para decirle a la caché cómo combinar listas con mutaciones y cómo funcionan juntas.

OK, ahora los clientes de GraphQL hacen algo aún más avanzado. Lo que estaba hablando y contándote es la caché a nivel de documento. Básicamente, cuando comenzamos, así es como la gente hacía la caché de GraphQL al principio. Tomaban todo el resultado de la consulta y lo ponían en la caché. Sin embargo, hoy en día, los clientes de GraphQL son aún más inteligentes que eso.

7. Caché Normalizada y Restricciones en el Edge

Short description:

Los clientes de GraphQL dividen la respuesta en objetos individuales y los almacenan en caché por separado. Esto permite una mejor experiencia de usuario al evitar viajes innecesarios a través de la red. Los clientes de GraphQL tienen una estructura de datos separada que vincula objetos relacionados. GraphQL es perfecto para la caché y funciona aún mejor que las API REST. Sin embargo, la caché en el edge tiene restricciones diferentes a la caché en el navegador.

Hacen algo llamado caché normalizada. Así que si volvemos a nuestro antiguo ejemplo de la obtención de una publicación de blog con la idea del título y el autor, en lugar de tomar toda esta respuesta que obtuvimos, en lugar de tomar todo esto y ponerlo en la caché, los clientes de GraphQL actualmente suelen dividir esto en objetos individuales. Entonces tomarán los datos de la publicación y los almacenarán en caché, pero luego tomarán los datos del usuario y los almacenarán en caché por separado. Esto termina viéndose algo así. Tienes en tu caché los datos de la publicación con el id5 y luego los datos del usuario con el id1.

¿Por qué harías eso? ¿Cuál es el punto? El punto es, imagina que ahora tengo una consulta para obtener un usuario, ¿verdad? Y digo, obtener usuario id1. Ahora la caché puede decir, oh, espera un momento, no has obtenido esta consulta específica antes que obtiene el usuario con el id1. Pero has obtenido el usuario con el id1 en esta otra consulta. Y puedo darte esos datos inmediatamente sin tener que ir al origen. Y así se logra una experiencia de usuario aún mejor porque se evitan muchos viajes a través de la red porque no tienes que ir a buscar muchos datos que ya has cargado en cualquier otra consulta en algún lugar anidado, ¿verdad? Ya conocemos los datos del usuario con el id1. Así que no tenemos que ir al servidor a obtenerlos. Podemos obtenerlos directamente de la caché.

Ahora lo único que falta aquí, por supuesto, es post.author, porque como sabemos, post.author corresponde al usuario con el id1. Y así los clientes de GraphQL tienen una estructura de datos separada que nos dice cómo vincular estos objetos entre sí. Y básicamente se ve algo así. Nos dice que para la publicación con el id5, el autor es el usuario con el id1. Básicamente almacena las relaciones y vínculos entre estos objetos para que si consultas post.author, sepa cómo resolverlo y sepa que eso significa que es el usuario con el id1. Así que eso es un poco sobre la caché normalizada y cómo realmente funcionan los clientes de GraphQL. GraphQL es increíble para la caché. Eso es lo que quiero que recuerdes. La gente dice, ya sabes, durante los últimos cinco años, ha sido, no puedes cachear GraphQL, ¿verdad? Cuando lees artículos sobre REST versus GraphQL, uno de los principales puntos que la gente menciona es, sí, GraphQL es genial, pero no puedes cachearlo. Y en mi cabeza pienso, eso no tiene sentido. GraphQL es realmente perfecto. Funciona incluso mejor que si construyeras una API REST aleatoria, ¿verdad? Claro, REST tiene Swagger y JSON API y otros estándares que también agregan esto, pero GraphQL también lo tiene. Y GraphQL es realmente increíble para la caché.

Entonces, volviendo a mi pregunta original, ¿por qué no puedo simplemente ejecutar un cliente de GraphQL en el edge, ¿verdad? ¿Por qué no puedo simplemente tomar esta caché que ya tengo en mi cliente de GraphQL y ejecutarla en un servidor? Ya están haciendo todo lo que necesito. Solo quiero tomar esto, ponerlo en un servidor para que nuestros servidores no se caigan más, ¿verdad? Solo quería resolver nuestro propio problema. Ahora, la parte complicada aquí es el edge. Porque resulta que almacenar en caché en el edge tiene restricciones ligeramente diferentes que almacenar en caché en el navegador.

8. Edge Caching and Authorization

Short description:

Utilizamos Fastly-Computed-Edge, que tiene 60 centros de datos en todo el mundo donde se puede ejecutar código Rust. Sin embargo, la caché en el edge no es tan simple como parece debido a la autorización. A diferencia de los clientes de GraphQL en los navegadores, la caché en el edge requiere tener en cuenta los permisos de acceso del usuario. Etiquetamos los resultados de las consultas en caché con tokens de autenticación para garantizar el acceso autorizado a los datos. Esta pieza crítica se pasó por alto inicialmente al implementar la caché de GraphQL en el edge.

Utilizamos Fastly-Computed-Edge. Lo siento, Sunil. No usamos Cloudflare. Utilizamos Fastly. Y Fastly-Computed-Edge tiene estos 60 centros de datos en todo el mundo que corresponden a donde han colocado sus máquinas en piezas aleatorias en todo el mundo. Y te permite ejecutar código, código Rust, en esos 60 centros de datos. Y eso es realmente genial. Y eso es realmente poderoso. Y es bastante agradable. Puedo implementar algo en los 60 centros de datos en todo el mundo. Genial. De acuerdo. De acuerdo.

Pero en realidad, la caché en el edge no es tan simple como pensaba, debido a la autorización. Esta es la principal diferencia entre los clientes de GraphQL y la caché en el edge. Porque si lo piensas, un cliente de GraphQL que se ejecuta en tu navegador, sabe que no funciona bajo la suposición de que todo lo que tiene en su caché puede ser accedido por cualquiera. No necesita preocuparse por la autorización, porque de todos modos está en tu navegador, ¿verdad? Sabe que si algo está en la caché, entonces puedes acceder a ello. Así que si solicitas el usuario con el ID uno, y lo tengo en la caché, puedo simplemente dártelo. Porque sé que ya lo has obtenido en tu navegador. Así que obviamente tienes acceso a ello. Así que no necesito preocuparme por eso. Eso no ocurre en el edge, ¿verdad? Si estás ejecutando algo en un servidor, recibes solicitudes de muchos usuarios diferentes a la misma caché, y de repente tienes que preocuparte por, vaya, en realidad esa persona no está autorizada para acceder a los datos del usuario con el ID uno. Vaya. No lo había pensado. Esto es ligeramente diferente a lo que hacen los clientes de GraphQL.

Así que si volvemos a nuestro resultado de consulta en caché aquí, en lugar de simplemente etiquetarlo con el post con el ID cinco y el usuario con el ID uno, también tenemos que etiquetarlo con un token de autenticación específico que utiliza la persona que envió la solicitud. Utilizamos algo como esto. Ahora, este token aleatorio de basura en base64 no está en ninguna parte de la consulta. Esto es metadatos que se envían con la solicitud, ya sea en una cookie o en el encabezado de autorización o en algún otro lugar. Etiquetamos cada resultado de consulta en caché con ese token, para que cuando verifiquemos, hey, ¿tenemos al usuario con el ID uno en la caché en algún lugar, tenemos esto en caché en algún lugar, entonces podemos decir, espera, ¿tenemos al usuario con el ID uno en caché para este token de autenticación específico? ¿Este usuario realmente tiene permiso para acceder a estos datos? Esto fue una pieza crítica importante que pasamos por alto al principio, cuando pensamos en tomar la caché de GraphQL y ponerla en el edge.

9. Global Cache Purging and GraphCDN

Short description:

Lo otro que es un poco más complicado es la purga de caché global. Tenemos 60 centros de datos en todo el mundo. Fastly tiene una purga de caché global increíblemente rápida. Fastly puede invalidar los resultados de consulta en caché a nivel mundial en 150 milisegundos. Van en ambas direcciones al mismo tiempo, ¿verdad? Ese es el truco. De todos modos, eso es increíble. GraphCDN surgió a partir de este problema en Spectrum. Intentamos durante meses hacer que esto funcionara y finalmente lo logramos, y eso es lo que es GraphCDN. Y eso es en lo que he estado trabajando durante los últimos meses, en el almacenamiento en caché gráfico.

Tal vez debamos tener un poco más de cuidado. Lo otro que es un poco más complicado es la purga de caché global, porque si estás en un navegador y una mutación pasa y dice editar publicación, bueno, simplemente eliminas ese objeto JavaScript. Todo está en la memoria de tu navegador, no importa, simplemente puedes eliminar esta publicación con el objeto D5 de tu objeto de caché y listo. Problema de invalidación de caché resuelto.

Tenemos 60 centros de datos en todo el mundo. Cuando vemos una mutación, no podemos simplemente decir, oh, vamos a eliminar esto de la memoria. No es tan simple como eso, porque tenemos que invalidarlo en todas partes, no solo en ese centro de datos en el que pasó la mutación. Afortunadamente, Fastly hace mucho de esto por nosotros, y esa también es una de las principales razones por las que usamos Fastly. Fastly tiene una purga de caché global increíblemente rápida. Tienen esta API donde puedes enviar una solicitud a Fastly y decir, mira, quiero invalidar esta etiqueta específica, digamos la publicación con tu D5, y Fastly invalidará el resultado de la consulta en caché en todas partes en el mundo en 150 milisegundos.

150 milisegundos. Cuando me enteré de eso, pensé, espera, ¿qué tan rápido es la velocidad de la luz, verdad? Para dar la vuelta al mundo una vez, y busqué esto, toma alrededor de 130 milisegundos, ¿verdad? La luz tarda alrededor de 130 milisegundos en dar una vuelta alrededor del globo. Fastly puede invalidar los resultados de consulta en caché a nivel mundial en 150 milisegundos. ¿Cómo tiene sentido eso? Es increíble. Por supuesto, el truco es que no tienen que dar la vuelta al mundo entero. Van en ambas direcciones al mismo tiempo, ¿verdad? Ese es el truco. Van en ambas direcciones al mismo tiempo, a mitad de camino alrededor del mundo, y así solo tienen que ir en esta dirección, y luego pueden hacerlo muy rápido.

De todos modos, eso es increíble. Y eso es realmente de donde surgió GraphCDN. Y tuvimos este problema en Spectrum, y yo no pude resolverlo. Y así, en la actualidad, pensamos, bueno, si tenemos este problema, tal vez otras personas también tengan este problema. Y así intentamos durante meses hacer que esto funcionara, y finalmente lo logramos, y eso es lo que es GraphCDN. Y eso es en lo que he estado trabajando durante los últimos meses, en el almacenamiento en caché gráfico. De acuerdo, gracias a todos por tenerme aquí. Tengo un montón de pegatinas, así que si me encuentras después, puedes tener una pegatina, ven y habla conmigo. Estoy encantado de darte una. Tengo suficientes para todos. Y gracias por tenerme aquí. Ha sido increíble. Aplausos Me gustaría una pegatina, por favor.

10. Clientes de GraphCDN y Historia de Éxito

Short description:

Creo que el logotipo de GraphCDN es realmente impresionante. Entonces, esta es la segunda o tercera vez que te veo dar una charla. GraphCDN ha estado en funcionamiento durante casi medio año. Hay algunos clientes que me han dejado muy impresionado. Uno reciente que podemos mencionar es italic.com. Estaban teniendo problemas con la escalabilidad y estaban utilizando GraphQL para el nuevo sitio web. Hemos captado, creo, el 90 o 95% del tráfico de su servicio.

Por supuesto. Aquí tienes. Lo primero es lo primero. Dos pegatinas cada uno. Entonces, ese fue en realidad mi primer comentario que quería hacer. Creo que el logotipo de GraphCDN es realmente impresionante. Gracias, lo aprecio. No sé si hiciste algo por el design, pero me encantó. Me encanta. Lo aprecio.

Entonces, esta es la segunda o tercera vez que te veo dar una charla. Siempre siento como si estuviera viendo a un mago dando una charla. Es realmente genial, las cosas de las que siempre hablas.

Mi primera pregunta para mí mismo es, GraphCDN ha estado en funcionamiento durante casi medio año, ¿verdad? Algo así, sí. ¿Hay algún cliente, sin mencionar nombres si no se te permite, que te haga decir, oh dios mío, están usando mi producto? Eso es increíble.

Hay algunos clientes que me han dejado muy impresionado. Uno reciente que podemos mencionar es italic.com. Y son como una tienda de e-commerce. Están tratando de ofrecerte productos de alta calidad sin una marca. Entonces, encuentran los fabricantes en China que son responsables de hacer bolsos de lujo, por ejemplo, ¿verdad? Encuentran la fábrica que hace bolsos de Dior. Y luego van a la fábrica y dicen, oye, danos los mismos bolsos, solo que no pongan el logotipo, ¿verdad? Danos los mismos bolsos, pero sin el logotipo. Y luego los venden casi al costo. Y es mucho, mucho más barato y de una calidad super alta. Y han estado creciendo como locos. Desafortunadamente, solo están disponibles en Estados Unidos, pero han estado creciendo como locos. Acaban de recaudar una cantidad seria en una ronda B o C y una cantidad increíble de dinero. Y estaban teniendo problemas con la escalabilidad. Y estaban utilizando GraphQL para el nuevo sitio web. Pusieron GraphQL al frente. Y hemos captado, creo, el 90 o 95% del tráfico de su servicio.

QnA

Introducción a Preguntas y Respuestas

Short description:

Y eso para mí es simplemente como, estoy feliz. ¿Sabes a lo que me refiero? Realmente resolvió el problema para alguien. Él es un buen hombre. Puedo imaginar. Felicitaciones. Quería recordar a todos, si hacen preguntas en Slido, pueden ganar camisetas por la mejor pregunta.

Y eso para mí es simplemente como, estoy feliz. ¿Sabes a lo que me refiero? Realmente resolvió el problema para alguien. Él es un buen hombre. Puedo imaginar. Felicitaciones. Quería recordar a todos, si hacen preguntas en Slido, pueden ganar camisetas por la mejor pregunta. No sabía esto. No puedes ganar una. ¿Vas a hacer preguntas para ti mismo? Voy a hacer una pregunta ahora mismo y ver si no puedo ganar. Pero para identificarte, necesitamos saber quién eres. Entonces, si haces una pregunta en Slido, asegúrate de usar tu nombre real. Y si estás viendo de forma remota, porque las personas remotas recibirán las camisetas enviadas si ganan la camiseta, asegúrate de usar tu nombre de usuario de Discord como tu nombre en Slido, también, para que podamos identificarte y encontrarte más tarde.

Manejo de la Caché de la Lista con Paginación

Short description:

La paginación hace que la caché sea complicada, especialmente con la validación. Intentamos proporcionar un control manual para manejar este problema. En Spectrum, invalidamos listas específicas de publicaciones en lugar de todas las publicaciones cuando se agrega una nueva publicación a una comunidad. Este es el problema más difícil en la caché de GraphQL, pero estamos trabajando para que sea más fácil. Contratamos a personas experimentadas del equipo Urkel para abordar este desafío. No tenemos nada en contra de Apollo o Relay, y la contratación del equipo Urkel fue coincidencia.

La primera pregunta es de Anna. ¿Cómo manejar correctamente la caché de una lista con paginación? Parece una operación bastante complicada.

Esa es una excelente pregunta. Sí. La paginación hace que la caché sea un poco más complicada, especialmente en la validation. Básicamente, con los clientes gráficos, tienes mucho control manual y tratamos de darte ese mismo control manual. Podemos decir, bueno, sé que, por ejemplo, en nuestro caso de uso en Spectrum, si alguien publica una nueva publicación, esa publicación se publicó en una community específica. Entonces sabíamos, bueno, no queremos invalidar todas las listas de publicaciones. Eso no tiene sentido, ¿verdad? Eso mataría nuestra caché. En cambio, lo que podríamos hacer es invalidar solo las listas de publicaciones de esa community, si eso tiene sentido. De esa manera, puedes solucionar un poco este problema de la lista, pero honestamente es el problema más difícil de la caché de GraphQL, y creo que tendremos que trabajar en hacerlo mucho más fácil, porque en este momento todavía es un poco complicado de manera manual implementar todo eso. Así que espero que podamos hacerlo más fácil en el futuro.

Afortunadamente, muchas personas de nuestro equipo han trabajado en la caché de GraphQL durante bastante tiempo, contratamos a muchas personas del equipo Urkel, por lo que si alguien puede resolverlo, ellos pueden. No soy lo suficientemente inteligente, pero si alguien puede, ellos pueden, y espero que lleguemos allí eventualmente.

Eres simplemente un líder visionario. No, solo soy un idiota en la habitación que no sabe lo que está haciendo. Genial.

Tenemos tiempo para otra pregunta, y esta es de, bueno, Anónimo. Bueno, dicen, felicitaciones por contratar a la mayoría del equipo principal de Urkel. ¿Estás apostando completamente por Urkel y por qué, en lugar de Apollo o Relay? Esa es una excelente pregunta. No, en realidad no tenemos nada que ver con Urkel. Quiero decir, lo usamos y estamos contentos con ello, pero no tenemos nada en contra de Apollo o Relay. El hecho de que muchos miembros del equipo principal de Urkel terminaran trabajando en Graf City fue algo casi por casualidad, porque simplemente estaban disponibles y buscaban trabajo, ¿verdad? Individualmente. No como grupo. Individualmente. Todas estas personas dejaron sus trabajos anteriores y estaban buscando nuevas oportunidades. Y nosotros dijimos, espera un momento. ¿Has trabajado con GraphQL Caching, verdad? ¿Quieres seguir trabajando con GraphQL Caching? Y afortunadamente, todos dijeron, sí, quiero hacer eso. Así es como sucedió. Pero no tenemos nada que ver con Urkel.

Caché de GraphQL y Datos Sensibles al Tiempo

Short description:

También trabajamos con Apollo y Relay. No importa qué cliente de GraphQL uses. Simplemente pasa tus solicitudes a través de nuestra puerta de enlace y las almacenaremos en caché en el borde. El manejo de la caché de GraphQL con datos sensibles al tiempo es un problema sin resolver, pero GraphQL está evolucionando con soluciones como defer y stream. Al dividir las consultas y almacenar en caché datos específicos, podemos proporcionar una experiencia de rendimiento para datos en vivo y estáticos. Estamos investigando este caso de uso común y esperamos encontrar una solución eventualmente.

Obviamente, ellos tienen tiempo para mantenerlo, pero sigue siendo un formidable proyecto de laboratorio y lo será en el futuro previsible. Y también trabajamos con Apollo y Relay. Para Graf City, realmente no importa qué cliente de GraphQL uses. Solo tienes que pasar todas tus solicitudes a través de nuestra puerta de enlace y las almacenaremos en caché en el borde sin problemas.

Muy bien, gracias. Haremos una más y nos extenderemos un poco en el tiempo. La pregunta es de Anónimo, así que no recibirán una camiseta. ¿Cómo manejarías la caché de GraphQL donde parte de los datos son datos sensibles al tiempo, como datos en vivo? Esa es otra excelente pregunta. Actualmente, esto también es un problema sin resolver. Sin embargo, GraphQL está evolucionando, y si has oído hablar de defer y stream, esos podrían ser posibles soluciones para eso. La forma en que funciona es cuando envías una consulta, podríamos analizar esa consulta y podríamos decir, bueno, esta información del ticker de acciones es realmente en tiempo real, y probablemente no deberíamos almacenar en caché eso porque de todos modos cambia cada segundo. No tiene sentido. Pero el artículo del blog que estás obteniendo al mismo tiempo, eso realmente se puede almacenar en caché. Entonces, con defer y stream y la división de consultas, podríamos dividirlas en dos consultas separadas en el borde, enviarlas al origen por separado y luego almacenar en caché solo el artículo del blog, y luego juntarlas y enviarlas al cliente. De esa manera, cuando envíes la misma consulta nuevamente, podríamos cargar el artículo del blog desde la caché y solo enviar la solicitud de datos en vivo al origen para obtener esos datos. Y luego, con stream y defer, incluso podríamos devolver ese artículo del blog al cliente antes de que el resto de los datos estén allí, lo que significa que sería muy eficiente, y tú, como usuario gráfico, no tendrías que hacer ningún trabajo para que esos datos en vivo sean en vivo, pero también los datos estáticos se almacenen en caché. Así que eso es algo que estamos investigando. Con suerte, llegaremos allí eventualmente, porque este es un caso de uso bastante común. Ya veremos, pero llegaremos allí eventualmente.

Muy bien. Bueno, ese es todo el tiempo que tenemos, desafortunadamente. Pero si tienes alguna pregunta, Max estará aquí todo el día, ¿verdad? Pegatinas. Ven a por pegatinas. Recuerden todos el sistema de aplausos en CSS. ¿Cuánto creemos que deberíamos ir?

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 Summit 2023React Summit 2023
26 min
Principles for Scaling Frontend Application Development
Top Content
After spending over a decade at Google, and now as the CTO of Vercel, Malte Ubl is no stranger to being responsible for a team’s software infrastructure. However, being in charge of defining how people write software, and in turn, building the infrastructure that they’re using to write said software, presents significant challenges. This presentation by Malte Ubl will uncover the guiding principles to leading a large software infrastructure.
React Advanced Conference 2021React Advanced Conference 2021
19 min
Automating All the Code & Testing Things with GitHub Actions
Top Content
Code tasks like linting and testing are critical pieces of a developer’s workflow that help keep us sane like preventing syntax or style issues and hardening our core business logic. We’ll talk about how we can use GitHub Actions to automate these tasks and help keep our projects running smoothly.
DevOps.js Conf 2022DevOps.js Conf 2022
33 min
Fine-tuning DevOps for People over Perfection
Top Content
Demand for DevOps has increased in recent years as more organizations adopt cloud native technologies. Complexity has also increased and a "zero to hero" mentality leaves many people chasing perfection and FOMO. This session focusses instead on why maybe we shouldn't adopt a technology practice and how sometimes teams can achieve the same results prioritizing people over ops automation & controls. Let's look at amounts of and fine-tuning everything as code, pull requests, DevSecOps, Monitoring and more to prioritize developer well-being over optimization perfection. It can be a valid decision to deploy less and sleep better. And finally we'll examine how manual practice and discipline can be the key to superb products and experiences.

Workshops on related 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 Summit 2023React Summit 2023
145 min
React at Scale with Nx
Top Content
Featured WorkshopFree
We're going to be using Nx and some its plugins to accelerate the development of this app.
Some of the things you'll learn:- Generating a pristine Nx workspace- Generating frontend React apps and backend APIs inside your workspace, with pre-configured proxies- Creating shared libs for re-using code- Generating new routed components with all the routes pre-configured by Nx and ready to go- How to organize code in a monorepo- Easily move libs around your folder structure- Creating Storybook stories and e2e Cypress tests for your components
Table of contents: - Lab 1 - Generate an empty workspace- Lab 2 - Generate a React app- Lab 3 - Executors- Lab 3.1 - Migrations- Lab 4 - Generate a component lib- Lab 5 - Generate a utility lib- Lab 6 - Generate a route lib- Lab 7 - Add an Express API- Lab 8 - Displaying a full game in the routed game-detail component- Lab 9 - Generate a type lib that the API and frontend can share- Lab 10 - Generate Storybook stories for the shared ui component- Lab 11 - E2E test the shared component
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