en Elogié a Google por decir “no” a las tentaciones de la modernidad. Arma de ingeniería secreta de Google Calendar: Restraint ¡Gracias por leer Fullstack Engineer! suscríbete gratis para recibir nuevos mensajes y apoyar mi trabajo. Subscríbete "Use a frontend framework." No. JavaScript. "Use Typescript." No. Javascript. "Use a trendy CSS tool." No. CSS classnames. "Give us a native desktop app." No. Browser. "Give us dark mode." No. "Make it really fast." No. Su compromiso con la simplicidad ha ayudado a GCal a defender su posición como el calendario predeterminado para miles de millones de personas normales. Para los clientes de API, sin embargo, esa misma simplicidad hace que la vida sea trágicamente complicada. Cómo crece esa complejidad y qué podemos aprender de ella como constructores. El problema: mantener los datos en sincronía Estás construyendo un nuevo calendario llamado Calendario Cool. Para ayudar a los usuarios a comenzar, les permite importar su calendario de Google existente. Esto requerirá acceso a los datos de Google Calendar de sus usuarios. Usted mira la API de GCal y ve los sospechosos típicos: “Cool,” usted piensa. “I just gotta get the , luego obtenga todos los eventos para ese calendario. Cuando necesite actualizar un evento, utilizaré el Desde el GET Respuesta » calendarId eventId events Todo esto se puede hacer con algunas funciones simples: Todos los eventos están en su DB, y también aparecen en el GCal del usuario después de que un usuario actualice un evento de su interfaz de usuario. Abre la aplicación GCal, crea un nuevo evento llamado “Celebrate at Denny’s”, y espera con impaciencia sus pancadas de canela. La aplicación Cool Cal está abierta, pero el nuevo evento no aparece. Su estómago vacío se hunde a medida que se da cuenta de que sólo ha implementado la mitad de la solución (CoolCal → GCal). Todavía necesita asegurarse de que los cambios de GCal se propaguen a Calendario fresco (GCal → CoolCal). Negación Usted sabe que otros han encontrado este caso de uso antes, por lo que vuelve a visitar los documentos de la API de GCal. Afortunadamente, usted encuentra una guía llamada " » » Sincronizar los recursos de manera efectiva La guía es corta, lo que te facilita. Parece que sólo tienes que añadir unas cuantas llamadas más. Dado que no sabes cuántos eventos se actualizaron o cuándo se actualizaron, sabes que necesitarás un ciclo para recuperar todos ellos. tiene sentido. Afortunadamente, los documentos incluyen un fragmento completo de esto en Java. Incluso utiliza el estrategia looping, que te hace sentir inteligente. do-while Seguro que puedes simplemente convertir eso en JavaScript y seguir adelante. La ira Ha pasado una hora, y usted ha convertido con éxito el fragmento a una función de JavaScript llamada Actualiza tu API. syncGcal() ¡Está funcionando! Cada vez que corras , los nuevos datos GCal de un usuario se agregan a CoolCal. syncGcal() Usted decide incluir el New York Style Cheesecake para sus problemas. Mientras estás en tu camino de salida, algunas preguntas surgen en tu cerebro cansado... El syncToken no persiste en ninguna parte syncGcal() sólo funciona cuando se llama manualmente How often should I run syncGcal() ? ¿Cada hora? ¿Cada minuto? Where will I store the token? ¿El almacenamiento local? El ¿La colección? user ¿Una nueva colección? What happens if the token becomes invalid? ¿Puedo seguir recorriendo? ¿Necesito hacer una importación completa como copia de seguridad? ¿Y los límites de las cuotas? ¿Qué pasa si un usuario hace un cambio durante este proceso? Usted se enojó - en la guía por no advertirle sobre estos casos marginales, entonces a su ingenuidad por asumir que debería. Negociación "No estoy solo - puedo llegar a pedir ayuda", te dices a ti mismo, al igual que practicaste en la terapia. Usted está seguro de que los documentos de la API tendrán un método llamado que tú has ignorado. syncResources() ¿O se ofrecerá como un servicio? como alguna empresa YC que sincronizará mágicamente todos sus datos para usted. Al menos, habrá un discípulo de Richard Stallman que tiene un repo del MIT al que puede apuntar a Claude. > clone the two-way sync stuff from github.com/stallman-cal. no bugs. Depresión Los documentos oficiales están en desuso. Todas las empresas YC son agentes de construcción. Stallman no confía en su aplicación de calendario para fines lucrativos. (Hay un proyecto MIT llamado , pero sólo tiene 200 estrellas. no se puede confiar.) Calendario de Compás Nadie se preocupa por su función de sincronización bidireccional. De hecho, están todos solos. Una sola lágrima cae sobre su teclado mecánico cuando se da cuenta de que no va a ir a Denny's hoy. aceptación Después de un brindis francés casero y un paseo postprandial, te acuerdo con tu destino para actuar como un verdadero ingeniero y hacerlo tú mismo. Unos días después, por fin está hecho. Pero todavía no puedes dejar de preguntarte “¿Por qué GCal lo hizo de esta manera?” “¿Debe haber sido tan complicado?” Los Requisitos Usted se pone en los zapatos de Google mediante la ingeniería inversa de los requisitos en forma de El PRD. Requisitos del producto Doc La solución Eso fue divertido, así que documenta la solución para cumplir con esos requisitos como un El TDD. Diseño Técnico Doc Análisis Finalmente, usted se siente calificado para decir si la solución de GCal "Dale 'em un token" fue una buena. Características de Token Pagination Pueden ocultar la complejidad del cliente para que no tengan que entender todo (replicación multi-regional, por ejemplo) Opaque tokens protect the client from overwhelm. Al controlar cuándo caducan los tokens, GCal puede asegurarse de que los clientes siempre vean la eliminación durante la sincronización incremental. Cleanly handles deletions. Google puede cambiar completamente su backend de almacenamiento, estrategia de sharding o topología sin afectar a los clientes. Esto seguramente hizo la migración de NoSQL (Megastore) a NewSQL (Spanner) más fácil en los años 2010 ( ) de Easier implementation changes. de alta calidad.com debilidades El webhook te dice algo cambiado, pero no lo que. Esto significa que cada notificación de empuje desencadena una nueva llamada de sincronización incremental. Esto se vuelve chatty cuando los usuarios de energía hacen ajustes frecuentes. ¿Por qué no incluir un dif ligero en la carga útil de empuje misma, o al menos indicar qué ID de evento cambió? Push is disconnected from sync. Los incrementales son incompatibles con la y Parámetros.Tienes que elegir un método u otro.Este es un problema para los humanos, que piensan en términos de tiempo más fácilmente que en tokens. Some filters are incompatible timeMin timeMax Los tokens de página son efímeros. Si un cliente se colapsa en medio de la página (después de la página 3 de 7), debe reiniciar toda la sincronización. Para los calendarios grandes, esto es doloroso. Una alternativa sería tokens de página duraderos que sobreviven a través de sesiones, o comprobar el progreso de la sincronización. No partial sync recovery. Alternativas (y por qué no fueron utilizadas) Líneas inferiores El sync token + cursor pagination es un Es el mismo patrón utilizado por Microsoft Graph (delta tokens), Stripe (cursores de página), y la mayoría de las APIs empresariales. pragmatic, battle-tested pattern Google lo eligió porque les permite ocultar la complejidad interna al tiempo que proporciona la semántica de sincronización "bastante buena" para el 99% de los casos de uso del calendario. Las alternativas (sourcing de eventos, CRDTs, OT) sólo tendrían sentido si GCal requería colaboración en tiempo real o sincronización P2P real fuera de línea. La imagen completa Si el objetivo de Google con GCal fuera generar ingresos, ofrecerían más documentos, vídeos y webinars.Habría un hermoso Defensor de Desarrolladores, un precio de API nivelado y un equipo de éxito del cliente. npm i gcal Pero el objetivo de Google con GCal es menos ambicioso: >> Don’t annoy regular users so much that they download Apple Calendar. No es justo esperar tanto de una API gratuita. Es increíble que puedas integrarte con GCal en primer lugar GCal honra su responsabilidad como parte fundamental de su aplicación priorizando la fiabilidad sobre la conveniencia de adopción: No ocurren muchos fracasos. La API hace lo que dicen sus documentos, incluso si no dicen mucho. No te sorprenden con los cambios Aún así, cuando piensan por primera vez: “Sé, simplemente me integraré con GCal”. there is a gap between the developer’s expectations and reality Actualmente, el desarrollador tiene que cerrar esa brecha con tiempo, esfuerzo y una pérdida de inocencia. Pero Google podría reducir el dolor al proporcionar más recursos. Por ejemplo, los documentos podrían ofrecer más orientación de implementación. Las muestras de código podrían evolucionar de repos desnudos a aplicaciones de demostración. En el equilibrio, mantener la API simple fue el paso correcto. Una API primitiva podría molestar a los usuarios de la energía. Pero si no afecta al UX, a los ingresos, a la retención o a la marca, manténlo simple. Takeaways para constructores Cuando se crea una API de sincronización pública Keep it boring: use existing standards Hemos visto aquí cómo la API de GCal se basa en la paginación del cursor y los tokens de sincronización.Su modelo de eventos también se construye en torno a estándares establecidos: CalDAV, iCalendar y RRULEs. En lugar de inventar sus versiones optimizadas, se adhieren a los básicos.Esta es una gran razón por la que ha habido tantas integraciones exitosas de GCal desde que su API se hizo público en 2006 (a diferencia de Yahoo). Use cursor pagination when the data is a moving target Cuando se producen escritos mientras se lee, se necesita consistencia en todas las páginas para evitar duplicados y líneas perdidas. Ejemplos: Calendarios, feeds, registros de auditoría, flujos de apéndices únicos. Use offset pagination when the data is stable Si los datos son estáticos y no tienen escritos simultáneos, se puede salir con un enfoque más simple. Ejemplo: resultados de búsqueda con números de página, tabla de administración para pequeños datos. Don’t oversell the API Usted sabe cómo es sentirse emocionado por la mañana para terminar un PR y luego para una caminata ... sólo para darse cuenta de que es más complicado de lo que pensaba y no ver la luz del día hasta la tarde siguiente. La API de Google no promete hacer todo por usted. El producto final venderá la API: pasa tu tiempo deleitando a tus usuarios con tu producto antes de preocuparse por deleitar a los desarrolladores que se integran con él. Don’t break things Si su integración es fundamental con el producto de otra persona, entonces vaya despacio. Gastar más tiempo probando la migración. Obtenga feedback sobre los documentos antes de lanzarlos. Envíe correos electrónicos y mensajes de terminal para que nadie se sorprenda. Esto requiere un cambio de identidad de “codificador de vibración de crackhead” que rompe las cosas en el prod a “ingeniero de software disciplinado”. No siempre lo conseguirás bien, pero tomas la responsabilidad en serio. Un cambio revolucionario hará más daño que tres características harán bien. La API de GCal es estable, por lo que mi puntuación de sueño, afortunadamente, no ha caído desde que lo uso. Cuando se integra una API de sincronización pública Don’t start with an integration “Pero mis usuarios no usarán mi app a menos que se integre con las herramientas que ya están utilizando”. “Pero mis usuarios no usarán mi app a menos que se integre con las herramientas que ya están utilizando”. Quizás, pero déjame que te lo digan. Agregar una integración es una búsqueda lateral costosa en su viaje al mercado de productos. Si el valor de prop es lo suficientemente bueno, no tendrán problema en crear una nueva cuenta y agregar datos desde cero. Accept that Pareto is right En otras palabras, el último 20% de las tareas tomará el 80% del tiempo. La superficie para los casos de borde y gotchas se amplía a medida que se implementa. Los documentos de Google no son los únicos que te van a seducir a pensar que las cosas pueden ser simples y gratuitas. Limpiar sus promesas considerando retries, idempotencia, fallback, sincronización delta, offline, invalidación de token, cuotas y solicitudes condicionales (ETags). No necesitas todos ellos para tu MVP, pero espera que salgan al final. Simplicity for one party means complexity for another UI simple y backend complejo Bueno para usuarios regulares → difícil para usuarios de energía Precio simple → complejo R&D API simple → Integración compleja La próxima vez que pienses, “Sólo usaré esta API gratuita, parece sencillo”, recuerde: It’s either free or simple; Someone always pays. Ahora vaya a tomar tus pancakes.