@octokit/rest изначально не является оригинальной разработкой GitHub, и представляет собой адаптацию github — самого популярного пакета 2017 года от пользователя @bkeepers. В этом посте будем говорить про @octokit/rest — теперь официальный JavaScript SDK для GitHub REST API. Позже переименованный в @octokit/rest, пакет github был одним из старейших проектов в экосистеме Node. Первый коммит сделан в июне 2010 года. Это были времена Node v0.1, когда package.json еще не существовал, а реестр npm был всё ещё в разработке. В 2017 году GitHub наняли меня, чтобы переработать пакет github в официальный GitHub API JavaScript SDK для браузеров и Node.js. Здесь можно найти мой первый коммит в сентябре 2017 года. На тот момент в проекте было около 16 тысяч строк кода, разбитых на три JavaScript файла, один огромный JSON и два файла для определений типов TypeScript/Flow. Первой основной целью проекта была поддерживаемость кода. Тогда ключевым компонентом библиотеки был огромный файл routes.json на почти 8 тысяч строк, который определял все конечные точки REST API GitHub. Его поддержка осуществлялась вручную, а создание/изменение роутов было следствием случайного обнаружения проблемы. Учитывая этот факт, я написал скрипт (octokit/routes) для автоматического анализа документации REST API GitHub и вывода результата в JSON. Это решило проблему поддержки routes.json. Если скрипт обнаруживал изменения, @octokit/rest получал PR с обновлениями файла routes.json, и после мерджа происходил автоматический релиз. Благодаря такой автоматизации, файл routes.json теперь гарантированно покрывал все конечные точки REST API GitHub и состоял из 10 275 строк кода. Сопутствующие определения типов TypeScript увеличились до более чем 26 700 строк кода. Как только вопрос полноты и поддерживаемости API был решен, я сосредоточился на другой цели проекта: модульность. JavaScript Octokit предназначен для всех сред выполнения JavaScript, некоторые из которых имеют строгие ограничения. Например, размер пакета является критическим показателем при использовании в браузере. Поэтому, вместо единой монолитной библиотеки, которая содержит полный REST API, стратегии аутентификации и рекомендованный вспомогательный функционал (например "пагинация"), важно предоставить пользователям доступ к более низкому уровню. Таким образом, будет возможен компромисс между размером пакета и предоставляемым функционалом. Вот обзор архитектуры, которую я разработал в январе 2018 года:  Результат внутреннего рефакторинга до новой архитектуры:
Обратите внимание, что этот пример был упрощен для удобства чтения В течение следующих шести месяцев я реорганизовал код и начал извлекать некоторые из модулей: В ноябре 2018 года, после использования плагинов внутри проекта в течение примерно шести месяцев, была анонсирована v16 включающая API для плагинов. Большая часть библиотеки была переведена на систему внутренних плагинов, для их дальнейшего извлечения. Новая архитектура внутреннего кода теперь выглядела так:
Обратите внимание, что этот пример был упрощен для удобства чтения Позже я создал @octokit/core — новую базовую библиотеку Octokit JavaScript, на которой будут основываться @octokit/rest и остальные библиотеки группы Octokit. Большая часть его логики была извлечена из @octokit/rest за исключением устаревших функций. Я не стал использовать его сразу в @octokit/rest, чтобы избежать критических изменений. Поскольку @octokit/core был свободен от любого legacy и проблем с обратной совместимостью, я продолжил эксперименты с разбивкой средств аутентификации. Результатом стали отдельные пакеты для каждой стратегии аутентификации — все они перечислены в README @octokit/auth. Если вы хотите узнать больше о стратегиях аутентификации GitHub, то предлагаю ознакомиться с моей серией статей (eng). @octokit/core и отдельные библиотеки аутентификации заменяют весь код из lib/* и plugins/authentication/*. Осталось только три плагина, которые я извлек в дальнейшем: Плагин validate устарел благодаря типизации от TypeScript во время компиляции и больше не было необходимости проверять параметры запроса на клиенте. Это значительно уменьшило количество кода и зависимостей. Например, вот текущее определение для метода octokit.checks.create(): Начиная с v17, определение того же метода выглядит следующим образом : В конце, ранее извлеченный код был собран в обещанные 10 строк: Каждая строка кода была изменена между версиями v16 и v17, поэтому единственный способ убедиться в отсутствии новых ошибок — провести полное тестирование. На момент создания модуля в 2017 году у нас не было никаких тестов, но были примеры использования. Первым делом я превратил их в интеграционные тесты, а поскольку JavaScript Octokit SDK задумывался как основа SDK для всех популярных языков, я создал octokit/fixtures — независимый от языка, автоматически обновляемый набор макетов http для общих случаев использования. Для оставшейся логики, специфичной для @octokit/rest, были написаны интеграционные тесты для 100% покрытия. На сегодняшний момент, если значение опустится ниже 100% тесты упадут. Работая над переходом на v17 с 10 строками кода, я продолжал запускать тесты из v16, за исключением тестов для устаревшего API. В то же время, слишком большое количество тестов не слишком хорошо, поэтому после успешной проверки v17, тесты не относящиеся к @octokit/rest были удалены. Некоторые из них были перенесены в плагины, @octokit/core или @octokit/request. На данный момент осталось несколько smoke-тестов и сценариев с использованием @octokit/fixtures. @octokit/rest начинался как пакет для REST API GitHub, но с 17 версии, это будет полноценная библиотека JavaScript, включающая вспомогательные функции для API @octokit/rest, с пагинацией, троттлингом и повторными запросами. Также будут поддерживаться все существующие и будущие стратегии аутентификации и GraphQL, так как он является частью @octokit/core. В конце, я хотел бы сказать спасибо Фабиану Джейкобсу, Майку де Буру и Джо Галло, которые создали и поддерживали модуль github до того, как он превратился в @octokit/rest. Web developer & designer