Local-primero es un nuevo paradigma para desarrollar aplicaciones, donde tus componentes hablan con una base de datos local incorporada y obtienes reactividad instantánea, sincronización multiusuario y soporte sin conflictos para trabajar sin conexión. ElectricSQL es una nueva plataforma de código abierto para el desarrollo local-primero de los inventores de CRDTs. Esta charla introduce el desarrollo local-primero y muestra cómo puedes desarrollar aplicaciones locales-primero reales hoy con React + ElectricSQL.
Software Local-Primero Con ElectricSQL
Video Summary and Transcription
El software local-primero permite la visualización instantánea de datos al usuario, ofreciendo cero latencia y funcionalidad sin conexión. Simplifica la sincronización de datos y permite la sincronización en tiempo real de múltiples usuarios. Herramientas populares como Facebook Messenger y las aplicaciones de Google Workspace han adoptado este patrón. Electric SQL proporciona una capa de sincronización para aplicaciones existentes, combinando funcionalidad en tiempo real con capacidades sin conflictos para trabajar sin conexión. El software local-primero reemplaza las APIs y los microservicios con un protocolo de replicación estandarizado, simplificando la gestión del estado y reduciendo la carga del servidor.
1. Introducción al Software LocalFirst
Hola. Mi nombre es James Arthur. Soy el CEO y uno de los cofundadores de Electric SQL. Hoy voy a hablar sobre el software local first y cómo puedes construirlo usando Electric React. En el desarrollo de software tradicional, la solicitud del usuario se envía al servidor a través de la red, y el servidor responde con el resultado. Sin embargo, con el software LocalFirst, la base de datos se traslada a la aplicación local, permitiendo la visualización instantánea de los datos al usuario. Este patrón ofrece cero latencia y funcionalidad fuera de línea, además de dar a los usuarios la propiedad de sus datos.
Hola. Mi nombre es James Arthur. Soy el CEO y uno de los cofundadores de Electric SQL. Y hoy voy a hablar sobre el software local first y cómo puedes construirlo usando Electric React. Así que para empezar, este es un diagrama bastante simplificado de, supongo, el desarrollo de software a la antigua. Muestra una arquitectura de tipo cloud first. El usuario llega, hace clic en el botón, se envía algún tipo de solicitud al servidor a través de la red. El servidor luego responde con el resultado. Esto podría ser una solicitud de página completa. Podría ser Ajax. Y luego muestras los resultados al usuario. Y si contrastas eso con el software LocalFirst, con LocalFirst, mueves la base de datos o almacén a la aplicación local, el usuario hace clic en el botón, va directamente a la base de datos local, y se muestra instantáneamente al usuario, y luego los datos se sincronizan a través de la red en segundo plano. Así que eso es más o menos de lo que estamos hablando como patrón. Y solo como una rápida orientación en términos de código. Así que este es un ejemplo de componente react que está configurado para trabajar de manera LocalFirst. Así tienes esta función add que es un manejador de callback, que está vinculado a un evento de clic. Llamas a este método create, y escribe directamente a una base de datos local incrustada, en este caso una base de datos SQLite. Luego puedes consultar esa base de datos local directamente en el código de la aplicación, y típicamente tienes un patrón en vivo o reactivo donde estás vinculando los resultados de la consulta a una variable de estado react. Así que eso es una orientación de lo que estamos hablando.
2. Beneficios del Patrón Local-First
Local-first es un patrón que elimina la dependencia de la red para las interacciones de la aplicación, proporcionando cero latencia y funcionalidad fuera de línea. Los usuarios tienen la propiedad de sus datos, y las aplicaciones pueden funcionar incluso cuando el back end está caído. Este patrón simplifica la sincronización de datos y permite la sincronización en tiempo real de múltiples usuarios. Aplicaciones modernas, como Figma y Linear, se construyen en este patrón para ofrecer una experiencia de usuario superior.
Entonces, ¿por qué es local-first un buen patrón o una buena idea? Si vuelves a este diagrama simple de nuevo, con este patrón cloud-first básicamente tienes la red en el camino de interacción, por lo que tu disponibilidad y tu latencia están ligeramente a merced de la conexión de red del usuario. Es muy importante diseñar una alta fiabilidad, como necesitas el servidor en línea para atender las solicitudes, por lo que empujas estos altos números de nueves, y es muy costoso hacer ese tipo de ingeniería de fiabilidad. Si las cosas tardan un tiempo en la red, el usuario está allí esperando un spinner de carga, están esperando que las cosas se carguen. Como desarrollador, porque estás escribiendo código que mueve data de un lado a otro a través de la red, tienes que escribir un montón de cosas para manejar errores de red y escenarios de fallo, y también porque los data tienden a ser almacenados en la cloud, es una especie de objetivo para lo que tienes hoy en día en torno a modelos donde las empresas ofrecen productos para obtener data de usuario para luego explotar los data y analizarlos y venderlos. Esos son algunos de los desafíos con este enfoque tradicional cloud-first. Con local-first, lo que obtienes es... Más bien, obviamente, porque mueves la base de datos local a la aplicación, no tienes la red en el camino de interacción, obtienes cero latencia. Las aplicaciones básicamente funcionan por defecto, por lo que funcionan fuera de línea incluso cuando la red está caída, funcionan incluso cuando el back-end está caído. Tienes esta primera copia de los data dentro de la aplicación local, por lo que los usuarios realmente poseen sus data. Porque tienes este tipo de cero latencia, tan pronto como un usuario hace algo, se muestra instantáneamente. Tienes este tipo de calidad de reactividad instantánea y sensación instantánea en las aplicaciones. Porque los data se sincronizan en segundo plano a través de la replicación activa-activa, obtienes esta sincronización natural en tiempo real de múltiples usuarios. También en muchos casos simplifica la operación del software porque mueves la forma en que estás moviendo los data de un lado a otro a través de la red, lejos de un conjunto completo de diferentes APIs y microservices a solo un protocolo de replicación estandarizado. Y significa que también el back-end simplemente no necesita ser diseñado para niveles tan altos de fiabilidad, porque las aplicaciones pueden funcionar incluso si el back-end está caído. Así que esa es una especie de introducción a por qué local-first, y creo que si miras muchas aplicaciones modernas que han estado alterando su sector o construyendo la mejor posible user experience, ahora están siendo construidas en este patrón, ¿verdad? Así que en el lado izquierdo, tienes Figma, por ejemplo, Figma fue recientemente comprado por Adobe por creo que 30 mil millones de dólares. Pero porque han podido construir un producto que tenía colaboración en tiempo real, y esta experiencia local-first incorporada directamente en él. Arriba a la derecha, tienes Linear, como Linear es un proyecto super ágil, de sensación instantánea
3. Adopción y Complejidad del Software Local-First
El software local-first está siendo adoptado por muchas herramientas y plataformas populares, como Facebook Messenger y las aplicaciones de Google Workspace. Ofrece reactividad instantánea y colaboración multiusuario, pero también introduce complejidad en los sistemas distribuidos. Electric, un proyecto con un equipo experimentado en sistemas de bases de datos distribuidas, tiene como objetivo proporcionar una capa de sincronización para las aplicaciones existentes construidas con Postgres y React, permitiendo los beneficios de los datos locales en primer lugar.
Y así, esa es básicamente nuestra especie de antecedentes como equipo. Así que, Electric es un proyecto. Surgió de probablemente los últimos 20, 30 años de investigación en los sistemas distribuidos que pueden operar en el lado AP del teorema CAP. Tenemos a dos de los tres inventores de CRDTs, por ejemplo, que es una primitiva clave para estos sistemas libres de conflictos en el equipo. Tenemos a Anet Benyusser, que lideró el desarrollo de AntidoteDB, que es la database geo-distribuida más advanced para trabajar desde el lado AP del teorema CAP. Y Walter y Kevin también son dos de los principales investigadores que han trabajado con Anet, Mark y Nuno a lo largo de los años. Así que, venimos del fondo de la ingeniería de estos tipos de sistemas de database distribuidos. Y luego hemos utilizado esa investigación para construir esta capa de sincronización para construir aplicaciones modernas. Y como mencioné antes, en términos de donde nos situamos fuera de estas capas de sincronización local en primer lugar, una de las cosas que hemos mirado alrededor de los sistemas en tiempo real es que es realmente útil si puedes básicamente tomar y soltarlos en una aplicación existente. Mientras que para hacer funcionar el tipo de local en primer lugar o cosas libres de conflictos, muchos de los nuevos sistemas han tenido que construir sus propios modelos de data y su propio mundo de alguna manera. Y así obtienes una especie de silo entre tus aplicaciones existentes que se construirían, digamos, algo como Postgres o tecnología estándar de database comparada con... Y luego el tipo de nuevos sistemas en tiempo real o sistemas en vivo donde terminas con un tipo de silo porque han tenido que trabajar con sus propios modelos de data y sus propias limitaciones para hacer que las cosas funcionen. Así que nuestro enfoque con Electric es básicamente construir esta capa de sincronización local en primer lugar, pero hacerlo de una manera que puedas simplemente soltar directamente en las aplicaciones existentes y específicamente las aplicaciones que se construyen con Postgres y React. Así que de alguna manera específicamente, es como una capa de sincronización que te da este tipo de mágicos datos locales en primer lugar encima de un modelo de datos de Postgres existente que se integra con
4. Demostración de la Plataforma y Características
Te mostraré la plataforma en electricsql.com, donde puedes explorar demos en vivo contrastando la sensación instantánea de Local First versus Cloud First. Local First ofrece reactividad instantánea y sincronización en tiempo real a través de la base de datos. Soporta múltiples bases de datos locales y funciona en entornos web y móviles. Combina funcionalidad en tiempo real con capacidades offline libres de conflictos, asegurando una fuerte consistencia eventual.
5. Capa de Sincronización y Sincronización Bidireccional
El software local-first proporciona resistencia a la conectividad de red y permite que las aplicaciones sigan funcionando. Mantiene la consistencia de los datos y la invariancia relacional, incluso en modo offline. La capa de sincronización incluye compensaciones técnicas para preservar la integridad referencial. La plataforma permite la replicación activa-activa y la sincronización bidireccional entre la base de datos y el estado de la interfaz de usuario.
Está formalmente probado que es el modelo de consistencia más fuerte que puedes tener para un sistema AP como este. Pero el resultado es básicamente para el usuario, es simplemente resistente a entrar y salir de la conectividad de red y las aplicaciones simplemente siguen funcionando.
Ahora, con eso, mencioné algo de esta complejidad de los sistemas distribuidos que obtienes con una especie de capa de sincronización como esta. Esta es una demostración que simplemente te muestra, por ejemplo, cómo, además de mantener la consistencia de los data, por lo que siempre terminas en el mismo estado, también preservamos la invariancia relacional. Así que, por ejemplo, cosas como la integridad referencial, por lo que no obtienes inconsistencias en tus data resultantes de este tipo de desafíos de concurrencia. Así que hay un ejemplo clásico donde esto es donde tienes jugadores que pueden inscribirse en torneos, por lo que básicamente puedes inscribir un torneo, y como ves, se sincroniza entre los dos dispositivos. Ahora, ¿qué sucede, por ejemplo, si desconectamos al usuario uno, inscribimos a un jugador en este segundo torneo aquí, mientras que concurrentemente este usuario elimina el torneo, básicamente tienes que tener una forma de preservar la integridad referencial. Y para esta demostración, usamos compensaciones técnicas, lo que significa que si eso sucede, el torneo se recrea. Así que básicamente hay un montón de cosas inteligentes incorporadas en la capa de sincronización, que está diseñada para mantener el tipo de garantías de nivel de database que tendrías codificando contra un sistema, como decir Prisma en la parte trasera, o simplemente codificando contra cualquier sistema de database, pero básicamente estamos permitiendo que funcione incluso cuando estás haciendo estas escrituras locales, incluso en un modo offline.
Y luego tal vez solo muestre una última cosa. Así que es replicación activa-activa, ¿verdad? Así hemos estado mostrando básicamente interactuando con el sistema a través de estos widgets incrustados en una página web. Básicamente, abriré un terminal aquí. Y Windows v. Windows. Así que lo que tenemos es básicamente el mismo tipo de mini demostración aquí, solo incrustada en la página. De nuevo, esto es todo simplemente código en vivo. Puedes ver si agarro aquí, lo que tenemos es algunas credenciales PSQL con alcance de usuario. Así que puedo simplemente conectarme directamente a la base de datos Postgres que está respaldando el sistema. Vamos a tener un vistazo aquí. Hay algunas de estas tablas que simplemente respaldaban las demostraciones, jugadores y torneos, etc. Y luego si vas aquí, por ejemplo, aquí hay un comando que puedo introducir en Postgres, que simplemente actualizará el deslizador a una posición aleatoria. Y como ves, si lo golpeo, puedo simplemente seguir moviendo el deslizador. Así que hay algunas cosas realmente interesantes aquí. Una es que puedes tener tu estado de UE en la database. Así que tienes una gestión de estado unificado entre tus data y tu estado de UE, lo cual es en realidad un cambio bastante profundo en términos de simplificar la forma en que haces el desarrollo de aplicaciones. Y también, lo que significa que no obtienes límites entre esos diferentes modelos entre el estado del cliente y los data persistidos. También, así que es bidireccional. Así que, por ejemplo, acabamos de ver básicamente actualizando un registro en la database y cómo se refleja aquí. Igualmente, si ejecuto este comando para básicamente ver el valor del deslizador, ves que a medida que muevo el deslizador
6. Sincronización Bidireccional y Publicación de Contenido
La sincronización bidireccional te permite usar la base de datos como un sistema de publicación de contenido. Es un patrón de publicación de contenido centralizado que sincroniza los datos inmediatamente en todas las aplicaciones locales. Esto permite una colaboración reactiva instantánea de varios usuarios. Tenemos una plantilla de inicio rápido para una aplicación estándar de React que configura los servicios necesarios, incluyendo Postgres y el componente del servicio de sincronización eléctrica. Todo es de código abierto y fácil de ejecutar usando Docker. La durabilidad es proporcionada por Postgres, y solo necesitas habilitar la replicación lógica.
Así que aquí estamos. Hemos creado la carpeta e instalado las dependencias, así que puedo entrar en la demo. Si encendemos el código aquí, entonces, por ejemplo, puedes ver que esto es simplemente una aplicación estándar de React.
7. Configurando la Conexión de la Base de Datos Eléctrica
Esta sección explica cómo configurar la conexión de la base de datos eléctrica utilizando SQLite incorporado. El proceso implica importar un adaptador WASQLite, instanciar la conexión de la base de datos y electrificarla para crear una conexión SQLite local. El esquema de la base de datos se define en Postgres y se propaga a los dispositivos locales a través de las migraciones. Se genera un cliente de base de datos seguro desde el esquema, proporcionando funciones para interactuar con la base de datos. Luego se puede iniciar la aplicación y se puede acceder a la base de datos para agregar elementos.
Y esto es, por ejemplo, donde nos gusta, este es el tipo de componente raíz donde hacemos algunas cosas para configurar la conexión de la base de datos eléctrica. La forma en que funciona es que tienes SQLite incorporado y en tu entorno, utilizando cualquier tipo de biblioteca que sería sensato para eso, luego tenemos un patrón de adaptador. En este caso, estamos importando un adaptador WASQLite, instanciando la conexión de la base de datos y luego la electrificamos para que tengas como una conexión SQLite local. Tienes tu esquema de base de datos, que te mostraré en un segundo, y solo tienes la configuración de eso como autenticación y tipo de URL para conectarte. Y luego lo ponemos en un proveedor, lo que significa que los componentes pueden obtener un control sobre este objeto de base de datos electrificado y lo usas un poco como el código que mostrábamos antes. Así que volviendo aquí, solo repasando estos pasos. Así que lo primero que podemos hacer es básicamente solo ejecutar los servicios de back-end, que tenemos envueltos en un archivo Docker Compose. Puedes ejecutar tu propio Postgres y puedes conectarlo eléctricamente, esto es básicamente que hemos empaquetado cosas para intentar hacer más fácil de ejecutar. Usualmente ese comando se ejecuta inmediatamente cuando estaba sucediendo. Bueno, acabo de reiniciar mi Docker allí y lo que voy a hacer es ahora ejecutar los servicios de respaldo, así que el Postgres y el eléctrico usando Docker Compose. Entonces, eso es tu propio back-end arriba, eso solo ejecuta los servicios.
Aquí estamos, ahora lo que puedo hacer es básicamente aplicar la migración de la base de datos. Entonces, lo que haces con electric es que defines tu esquema de base de datos en Postgres y luego el esquema se propaga a los dispositivos locales. Entonces, justo aquí, por ejemplo, si miras en db.migrations, sí, aquí tenemos un archivo SQL muy simple que simplemente define una tabla de elementos y luego la electrificamos. Entonces, esa tabla se sincroniza a través de la maquinaria de replicación. Entonces, puedo simplemente aplicar esa migración a Postgres aquí. Y luego, por ejemplo, si entramos, podemos conectarnos al Postgres local, lo siento, y comando y luego podemos ver que se ha creado una tabla de elementos. Esa tabla de elementos tiene algunos disparadores que agregamos. Disparadores en una tabla de sombras que agregamos para hacer algunas de las cosas inteligentes de fusión libre de conflictos. Y luego lo que haces es que generas un cliente de base de datos seguro desde el esquema de la base de datos. Entonces, si ahora ejecuto client.generate, esto básicamente lee la parte electrificada del esquema y genera una biblioteca de cliente segura. Entonces, puedes ver eso aquí, por ejemplo, si entramos aquí, y usa la maquinaria de Prisma y Zodd, y básicamente obtienes un montón de funciones. Entonces, aquí solo tenemos como una tabla de elementos y hay varias funciones que puedes llamar en ella, y cuando las usas en tu ID, todas son seguras. Y también incluye las migraciones iniciales en la aplicación para que cuando construyas tu aplicación local, sabe el esquema de base de datos con el que está trabajando. Y luego acepta migraciones en curso sobre la corriente de replicación. Y entonces, con eso en su lugar, ahora puedo iniciar la aplicación y básicamente obtienes una aplicación muy simple que solo está usando SQL eléctrico. Y puedes, si simplemente nos metemos en el código, es muy similar al ejemplo que te mostré al principio. Entonces, este fue el código de instanciación que revisamos antes. Y luego aquí en los componentes, obtenemos un control sobre la base de datos. Haces esta escritura directa a la base de datos local cuando estás
8. Software Local Primero y Modelo de Desarrollo
Tienes una consulta en vivo que recupera todos los elementos de una base de datos local. La maquinaria de sincronización basada en formas te permite controlar qué datos se sincronizan con los dispositivos locales. Puedes definir subconjuntos filtrados de datos y vincularlos a tus componentes utilizando consultas en vivo. La experiencia del usuario es instantánea y sin interrupciones, sin demoras ni indicadores de carga. El Software Local Primero proporciona una experiencia de usuario de alta calidad, colaboración incorporada y soporte fuera de línea. También ofrece beneficios como la propiedad de los datos y una mejor experiencia para el desarrollador. La base de datos local simplifica la gestión del estado y reduce la carga en los sistemas del servidor. Las API y los microservicios son reemplazados por un protocolo de replicación estandarizado.
Tal vez solo para saltar a una cosa más aquí. Entonces, hemos mostrado este ejemplo muy básico. Una aplicación un poco más realista aquí es que tenemos un clon lineal construido con SQL eléctrico y puedes usarlo. Y básicamente, como ves, toda la interacción es simplemente instantánea, ¿verdad? No hay demoras, no hay indicadores de carga, todo simplemente funciona inmediatamente. Y puedes venir y crear un nuevo problema, y todo entra. Entonces, obtienes una idea de esta calidad de la user experience y todo aquí está en vivo. Entonces, si abrimos otra ventana del navegador y haces estos cambios, los verás todos simplemente como si estuviéramos viendo con las demostraciones anteriores. Entonces, espero que te dé un poco de sabor del sistema y del modelo de desarrollo. Puedes venir, toda la documentation aquí está en nuestro sitio web, ElectricSQL. Tal vez solo para terminar, volver a la presentación. Entonces, recapitulando sobre el Software Local Primero en general, es mejor para todos los involucrados. Como, para el usuario, obtienes esta experiencia de usuario de muy alta calidad, obtienes aplicaciones que simplemente funcionan, que son resistentes a la red o al backend que está caído. Obtienes esta encantadora combinación de sensación instantánea, colaboración incorporada y soporte fuera de línea. También obtienes propiedad de data y otros beneficios más amplios. Además, para el desarrollador, lo que hemos estado viendo de empresas como Muse y como Linear, que han estado construyendo estas aplicaciones, es que han estado informando que en realidad la developer experience también es mucho más agradable. A, hay una gran cantidad de código menos que tienes que escribir porque no estás haciendo esta capa de transferencia de estado imperativa. Y también, dependiendo de cómo lo hagas, pero puedes evitar retrocesos y tentatividad. Entonces, básicamente estás escribiendo con esta base de datos local sin tener que involucrarte con la programación de la red en absoluto. Y también, hay cosas agradables alrededor de tener la base de datos local disponible para nosotros como debug, replicar estado, etc. Obtienes esta gestión de estado unificada. Y para el operador también, tiende a ser mucho, mucho más simple. A, reduces mucha de la carga en los sistemas del servidor porque tienes esta especie de almacenamiento en caché óptimo dentro del dispositivo local. Y también, reemplazas nuestras API y microservices con este protocolo de replicación mucho más simple, tipo de
9. Recursos e Información
Si quieres aprender más sobre el desarrollo LocalFIRST, hay una gran comunidad llamada la Comunidad Web LocalFIRST. Tienen un Discord activo y un sitio web con valiosos recursos. Electric SQL es una capa de sincronización LocalFIRST que funciona sobre PostgreSQL. Es compatible con los modelos de datos existentes y proporciona un cliente seguro por tipo y un modelo de sincronización basado en formas. Ofrece consultas en vivo, escrituras locales e integraciones con el marco de trabajo React. Para obtener más información, visita electricsql.com y únete a nuestra comunidad en Discord.
Y para obtener más información sobre Electric, este es nuestro sitio web, electricsql.com. Tenemos una comunidad en Discord, a la que eres muy bienvenido a unirte. Si tienes alguna pregunta o quieres discutir algo o necesitas ayuda para construir aplicaciones. Y puedes ver nuestro GitHub, todo es de código abierto y desarrollado en ElectricSQL. Slash Electric. Muchas gracias. El código QR aquí va a electricsql.com. Gracias.
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
Workshops on related topic
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
Table of contents:
1 - The infamous "N+1" problem: Jonathan Baker - Let's talk about what it is, why it is a problem, and how Shopify handles it at scale across several GraphQL APIs.
2 - Contextualizing GraphQL APIs: Alex Ackerman - How and why we decided to use directives. I’ll share what directives are, which directives are available out of the box, and how to create custom directives.
3 - Faster GraphQL queries for mobile clients: Theo Ben Hassen - As your mobile app grows, so will your GraphQL queries. In this talk, I will go over diverse strategies to make your queries faster and more effective.
4 - Building tomorrow’s product today: Greg MacWilliam - How Shopify adopts future features in today’s code.
5 - Managing large APIs effectively: Rebecca Friedman - We have thousands of developers at Shopify. Let’s take a look at how we’re ensuring the quality and consistency of our GraphQL APIs with so many contributors.
Join developers Aspen Smith and Nick Marino to see how you can change one line of config in your app and use ReadySet to scale up your query performance by orders of magnitude today.