В Я похвалил Google за то, что он безжалостно сказал «нет» искушениям современности. Секретное инженерное оружие Google Calendar: ограничение Спасибо за прочтение Fullstack Engineer! подписывайтесь бесплатно, чтобы получать новые сообщения и поддерживать мою работу. Подписаться "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. Их приверженность простоте помогла GCal защитить свою позицию как стандартного календаря для миллиардов обычных людей. Однако для клиентов API такая же простота делает жизнь трагически сложной. Как эта сложность проникает, и что мы можем извлечь из нее как строители. Проблема: сохранение данных в синхронном режиме Вы создаете новый классный календарь под названием Cool Calendar. Чтобы помочь пользователям начать, вы разрешаете им импортировать существующий Календарь Google. Для этого потребуется доступ к данным календаря Google ваших пользователей. Вы смотрите на API GCal и видите типичных подозреваемых: «Cool», ты думаешь, «I just gotta get the , затем получите все события для этого календаря. Когда мне нужно обновить событие, я использую Из GET Ответ » calendarId eventId events Все это можно сделать с помощью нескольких простых функций: Все события находятся в вашем DB, и они также появляются в GCal пользователя после того, как пользователь обновляет событие из вашего интерфейса. Вы открываете приложение GCal, создаете новое мероприятие под названием «Праздновать в Denny's» и с нетерпением ждете своих колбасы из корицы. Приложение Cool Cal открыто, но новое событие не появляется. Ваш пустой желудок опускается, когда вы понимаете, что реализовали только половину решения (CoolCal → GCal). Вы все еще должны убедиться, что изменения GCal распространяются на Cool Calendar (GCal → CoolCal). отрицать Вы знаете, что другие уже сталкивались с этим случаем использования, поэтому вы снова посещаете GCal API-документы. К счастью, вы нашли гида под названием « «» Синхронизируйте ресурсы эффективно Руководство короткое, что облегчает ваше поведение. Кажется, вам просто нужно добавить еще несколько звонков. Поскольку вы не знаете, сколько событий было обновлено или когда они были, вы знаете, что вам понадобится цепь, чтобы получить их все. Это имеет смысл. К счастью, в документах содержится полный фрагмент этого в Java. Он даже использует Стратегия, которая заставляет вас чувствовать себя умным. do-while Конечно, вы можете просто конвертировать это в JavaScript и продолжить. Гнев Прошло час, и вы успешно преобразовали фрагмент в функцию JavaScript под названием Обновить свой API. syncGcal() Это работает ! Каждый раз, когда вы бегаете , новые данные GCal пользователя добавляются в CoolCal. syncGcal() Вы решили включить New York Style Cheesecake для ваших проблем. По мере того, как вы выходите, несколько вопросов возникают в вашем усталом мозге... SyncToken не сохраняется нигде syncGcal() работает только тогда, когда он вызван вручную How often should I run syncGcal() ? Каждый час ? Каждую минуту? Where will I store the token? Местные склады ? ТЭ Сборник ? user Новая коллекция ? What happens if the token becomes invalid? Могу ли я продолжать ретринг? Нужно ли делать полный импорт в качестве резервного копирования? А как же квоты? Что делать, если пользователь вносит изменения в этот процесс? Вы разгневаетесь — на руководство за то, что не предупреждали вас об этих крайних случаях, а затем на вашу наивность за то, что считаете, что это должно быть. Переговоры «Я не один — я могу обратиться за помощью», — вы говорите себе, как вы практиковали в терапии. Вы уверены, что API-документы будут иметь метод под названием Что вы пренебрегали. syncResources() Или он будет предлагаться в качестве услуги? Как какая-то компания YC, которая магически синхронизирует все ваши данные для вас. По крайней мере, будет ученик Ричарда Сталлмана, у которого есть репо MIT, на которое вы можете указать Клода. > clone the two-way sync stuff from github.com/stallman-cal. no bugs. депрессии Официальные доски остаются. Все компании YC являются строительными агентами. Stallman не доверяет вашему приложению для получения прибыли. (Существует проект MIT под названием Но у него всего 200 звезд, на которые нельзя положиться.) Календарь компаса Никто не заботится о вашей двухсторонней синхронизации. На самом деле вы все одиноки. Одна слеза падает на вашу механическую клавиатуру, когда вы понимаете, что сегодня вы не будете ходить в Денни. Принятие После домашнего французского тоста и последующей прогулки вы соглашаетесь со своей судьбой вести себя как настоящий инженер и делать это самостоятельно. Спустя несколько недель, наконец, все закончилось. Но вы все еще не можете перестать удивляться «Почему GCal сделал это таким образом?» «Неужели это должно было быть так сложно?» требований Вы вкладываете себя в обувь Google, обращая требования в виде (с помощью PRD ) Требования к продукции Doc Решение Это было забавно, поэтому вы документируете решение для удовлетворения этих требований как и тдд. Технический дизайн doc Анализ Наконец, вы чувствуете себя квалифицированным, чтобы сказать, было ли решение GCal "Give 'em a token" хорошим. Сильные стороны Token Pagination Они могут скрыть сложность от клиента, так что им не нужно понимать все (например, многорегиональное воспроизведение). Opaque tokens protect the client from overwhelm. Контролируя истечение срока действия токенов, GCal может гарантировать, что клиенты всегда видят удаления во время синхронизации. Cleanly handles deletions. Google может полностью изменить свою стратегию хранения, разборку или топологию, не затрагивая клиентов. Это, безусловно, упростило миграцию из NoSQL (Megastore) в NewSQL (Spanner) в 2010-х годах ( ) Easier implementation changes. Высокое качество.com Слабости Webhook говорит вам что-то изменилось, но не что. Это означает, что каждое push-уведомление запускает новый всплеск синхронизации.Это становится частым, когда пользователи электроэнергии делают частые настройки.Почему бы не включить легкий дифф в саму push-загрузку или, по крайней мере, указать, какие идентификаторы событий изменились? Push is disconnected from sync. Интенсивные синхронизации несовместимы с и Вы должны выбрать один метод или другой.Это беда для людей, которые думают в плане времени легче, чем в токенах. Some filters are incompatible timeMin timeMax Токены страницы являются временными. Если клиент потерпит крах в середине страницы (после страницы 3 из 7), они должны перезапустить весь синхронизатор. Для больших календарей это болезненно. Альтернативой будут прочные токены страницы, которые выживают через сессии, или проверка прогресса синхронизации. No partial sync recovery. Альтернативы (и почему они не использовались) Нижняя линия Подход синхронизации токенов + курсоров является Это тот же шаблон, который используется Microsoft Graph (дельта-токены), Stripe (страничные курсоры) и большинством корпоративных API. pragmatic, battle-tested pattern Google выбрал его, потому что он позволяет скрыть внутреннюю сложность, предоставляя «достаточно хорошую» семантику синхронизации для 99% случаев использования календаря. Альтернативы (закупка событий, CRDT, OT) имеют смысл только в том случае, если GCal требует сотрудничества в режиме реального времени или подлинного синхронизации P2P. Полная картина Если цель Google с GCal была бы генерировать доходы, они предложили бы больше документов, видео и вебинаров.Будет красивый Защитник разработчиков, ценообразование API и команда успеха клиентов. npm i gcal Но цель Google с GCal менее амбициозна: >> Don’t annoy regular users so much that they download Apple Calendar. Несправедливо ожидать столько от бесплатного API. Удивительно, что вы можете интегрироваться с GCal в первую очередь GCal уважает свою ответственность как фундаментальную часть вашего приложения, отдавая приоритет надежности над удобством принятия: Не так много неудач случается. API делает то, что говорят его документы, даже если они не говорят много. Они не удивляют вас разрушительными изменениями все еще, когда они сначала думают: «Я знаю, я просто интегрируюсь с GCal». there is a gap between the developer’s expectations and reality В настоящее время разработчику приходится закрывать этот пробел временем, усилиями и потерей невиновности. Но Google может уменьшить боль, предоставив больше ресурсов. Например, docs могут предложить больше руководства по внедрению. Образцы кода могут развиваться от голой репозиции до демо-приложений. На балансе, сохранение простоты API было правильным шагом. Примитивный API может раздражать пользователей электроэнергии. Но если это не влияет на UX, доходы, сохранение или бренд, то держите это просто. Takeaways для строителей При создании публичного синхронизированного API Keep it boring: use existing standards Мы видели, как API GCal построен на курсорной пагинации и синхронизации токенов. Его модель событий также построена вокруг установленных стандартов: CalDAV, iCalendar и RRULEs. Вместо того чтобы изобретать свои оптимизированные версии, они придерживаются основ.Это большая причина, почему было так много успешных интеграций GCal с тех пор, как их API стал публичным в 2006 году (в отличие от Yahoo). Use cursor pagination when the data is a moving target Когда во время чтения появляются письма, вам нужна последовательность на страницах, чтобы избежать дублировок и пропущенных строк. Примеры: календари, потоки, журналы аудита, потоки только в приложении. Use offset pagination when the data is stable Если данные статичны и не имеют одновременных записей, вы можете избавиться от них с помощью более простого подхода. Пример: результаты поиска с номерами страниц, таблица администрирования для малых данных. Don’t oversell the API Вы знаете, как это чувствует, чтобы быть взволнованным по утрам, чтобы закончить PR, а затем на поход ... только чтобы осознать, что это более сложно, чем вы думали, и не увидеть свет до следующего дня. API Google не обещает сделать все за вас. Конечный продукт будет продавать API: потратьте время, чтобы порадовать своих пользователей своим продуктом, прежде чем беспокоиться о том, чтобы порадовать разработчиков, которые интегрируются с ним Don’t break things Если ваша интеграция является фундаментальной для продукта другого человека, то идти медленно. Проведите больше времени на тестирование миграции. Получите обратную связь о документах перед их запуском. Отправляйте «главы вверх» электронные письма и терминальные сообщения, чтобы никто не был удивлен. Для этого необходим сдвиг личности от «кодера вспышек» к «дисциплинированному инженеру программного обеспечения». Вы не всегда добьетесь успеха, но берете ответственность всерьез. Одно изменение сделает больше вреда, чем три функции сделают добро. API GCal стабилен, поэтому мой балл по сну, к счастью, не снизился с тех пор, как я его использовал. При интеграции публичного синхронизированного API Don’t start with an integration «Но мои пользователи не будут использовать мое приложение, если оно не интегрируется с инструментами, которые они уже используют». «Но мои пользователи не будут использовать мое приложение, если оно не интегрируется с инструментами, которые они уже используют». Возможно, но пусть они вам об этом расскажут. Добавление интеграции - это дорогостоящее побочное задание в вашем путешествии на рынке продуктов. Если поддержка стоимости достаточно хороша, у них не возникнет проблем с созданием новой учетной записи и добавлением данных с нуля. Accept that Pareto is right Другими словами, последние 20% задач займут 80% времени. Поверхность для краевых корпусов и гоча расширяется по мере реализации. Документы Google не единственные, которые будут соблазнить вас думать, что вещи могут быть простыми и бесплатными. Ограничьте свои обещания, рассматривая ретрии, idempotency, fallback, синхронизацию дельта, офлайн, недействительность токенов, квоты и условные запросы (ETags). Вам не нужны все они для вашего MVP, но ожидайте, что в конечном итоге они появятся. Simplicity for one party means complexity for another Простой UI → Комплексный backend Хорошо для обычных пользователей, трудно для энергопользователей Простое ценообразование → Сложные R&D Простое API → Сложная интеграция В следующий раз, когда вы подумаете: «Я просто использую этот бесплатный API, он выглядит просто», помните: It’s either free or simple; Someone always pays. А теперь пойди и возьми свои пирожные.