- Регистрация
- 23.09.18
- Сообщения
- 12.347
- Реакции
- 176
- Репутация
- 0

@octokit/rest изначально не является оригинальной разработкой GitHub, и представляет собой адаптацию
You must be registered for see links
— самого популярного пакета 2017 года от пользователя
You must be registered for see links
. В этом посте будем говорить про
You must be registered for see links
— теперь официальный JavaScript SDK для
You must be registered for see links
.Грегор (автор статьи) является разработчиком JavaScript Octokit. Он бывалый open source разработчик, с особой тягой к автоматизации задач и снижению порога вхождения для контрибьюторов всех видов и профессий. Помимо Octokit, Грегор работает над
You must be registered for see links
,
You must be registered for see links
и
You must be registered for see links
. В свободное время он заботится о своих тройняшках Нико, Аде и Киане. Больше материалов Грегора можно найти на
You must be registered for see links
и
You must be registered for see links
.legacy
Позже переименованный в @octokit/rest, пакет github был одним из старейших проектов в экосистеме Node.
You must be registered for see links
сделан в июне 2010 года. Это были времена
You must be registered for see links
, когда package.json еще не существовал, а реестр npm был всё ещё в разработке.В 2017 году GitHub наняли меня, чтобы переработать пакет github в официальный GitHub API JavaScript SDK для браузеров и Node.js. Здесь можно найти
You must be registered for see links
в сентябре 2017 года. На тот момент в проекте было около 16 тысяч строк кода, разбитых на три JavaScript файла, один огромный JSON и два файла для определений типов TypeScript/Flow.➜ rest.js git
120 lib/error.js
3246 lib/index.d.ts
905 lib/index.js
3232 lib/index.js.flow
17 lib/promise.js
7995 lib/routes.json
143 lib/util.js
15658 total
Разработка
Первой основной целью проекта была поддерживаемость кода. Тогда ключевым компонентом библиотеки был огромный файл
You must be registered for see links
на почти 8 тысяч строк, который определял все конечные точки REST API GitHub. Его поддержка осуществлялась вручную, а создание/изменение роутов было следствием
You must be registered for see links
.Учитывая этот факт, я написал скрипт (
You must be registered for see links
) для автоматического анализа документации REST API GitHub и вывода результата в JSON. Это решило проблему поддержки routes.json. Если скрипт обнаруживал изменения, @octokit/rest получал PR с обновлениями файла routes.json, и после мерджа происходил автоматический релиз. Благодаря такой автоматизации, файл routes.json теперь гарантированно покрывал все конечные точки REST API GitHub и состоял из
You must be registered for see links
. Сопутствующие определения типов TypeScript увеличились до более чем
You must be registered for see links
.Архитектура
Как только вопрос полноте и поддерживаемости API был решен, я сосредоточился на другой цели проекта:
You must be registered for see links
.Прим. переводчика: В оригинальной статье используется термин "decomposability", который дословно можно перевести как "разложимость", что не совсем удачно передает смысл. Здесь имеется ввиду "разделение на части", что можно объяснить как "разделение на модули" или "модульность".
JavaScript Octokit предназначен для всех сред выполнения JavaScript, некоторые из которых имеют строгие ограничения. Например, размер пакета является критическим показателем при использовании в браузере. Поэтому, вместо единой монолитной библиотеки, которая содержит полный REST API, стратегии аутентификации и рекомендованный вспомогательный функционал (например "пагинация"), важно предоставить пользователям доступ к более низкому уровню. Таким образом, будет возможен компромисс между размером пакета и предоставляемым функционалом.
Вот
You must be registered for see links
архитектуры, которую я разработал в январе 2018 года:
Результат внутреннего рефакторинга до новой архитектуры:
Обратите внимание, что этот пример был упрощен для удобства чтения
➜ rest.js git
31 index.js
3474 index.d.ts
3441 index.js.flow
101 lib/endpoint/ # 4 files
162 lib/request/ # 3 files
83 lib/plugins/authentication/ # 3 files
130 lib/plugins/endpoint-methods/ # 4 files
130 lib/plugins/pagination/ # 11 files
58 lib/parse-client-options.js
10628 lib/routes.json
18238 total
В течение следующих шести месяцев я реорганизовал код и начал извлекать некоторые из модулей:
-
You must be registered for see links: превращает параметры конечной точки API REST в общие параметры http-запроса
-
You must be registered for see links: отправляет параметризованные запросы в API GitHub с разумными настройками по умолчанию в браузерах и Node
-
You must be registered for see links: API использующееся для подключения к жизненному циклу запроса
В ноябре 2018 года, после использования плагинов внутри проекта в течение примерно шести месяцев, была анонсирована
You must be registered for see links
включающая API для плагинов. Большая часть библиотеки была переведена на систему
You must be registered for see links
, для их дальнейшего извлечения.Новая архитектура внутреннего кода теперь выглядела так:
Обратите внимание, что этот пример был упрощен для удобства чтения
➜ rest.js git
14 index.js
26714 index.d.ts
110 lib/ # 6 files
86 plugins/authentication/ # 3 files
77 plugins/pagination/ # 3 files
39 plugins/register-endpoints/ # 3 files
108 plugins/validate/ # 2 files
10275 plugins/rest-api-endpoints/routes.json
37423 total
Позже я создал
You must be registered for see links
— новую базовую библиотеку Octokit JavaScript, на которой будут основываться @octokit/rest и остальные библиотеки группы Octokit. Большая часть его логики была извлечена из @octokit/rest за исключением устаревших функций. Я не стал использовать его сразу в @octokit/rest, чтобы избежать критических изменений.Поскольку @octokit/core был свободен от любого legacy и проблем с обратной совместимостью, я продолжил эксперименты с разбивкой средств аутентификации. Результатом стали отдельные пакеты для каждой стратегии аутентификации — все они перечислены в
You must be registered for see links
. Если вы хотите узнать больше о стратегиях аутентификации GitHub, то предлагаю ознакомиться с моей
You must be registered for see links
.@octokit/core и отдельные библиотеки аутентификации заменяют весь код из lib/* и plugins/authentication/*. Осталось только три плагина, которые я извлек в дальнейшем:
-
You must be registered for see links
-
You must be registered for see links
-
You must be registered for see links
Плагин validate устарел благодаря типизации от TypeScript во время компиляции и больше не было необходимости проверять параметры запроса на клиенте. Это значительно уменьшило количество кода и зависимостей. Например, вот текущее определение для метода octokit.checks.create():
{
checks: {
create: {
headers: { accept: "application/vnd.github.antiope-preview+json" },
method: "POST",
params: {
actions: { type: "object[]" },
"actions[].description": { required: true, type: "string" },
"actions[].identifier": { required: true, type: "string" },
"actions[].label": { required: true, type: "string" },
completed_at: { type: "string" },
conclusion: {
enum: [
"success",
"failure",
"neutral",
"cancelled",
"timed_out",
"action_required"
],
type: "string"
},
details_url: { type: "string" },
external_id: { type: "string" },
head_sha: { required: true, type: "string" },
name: { required: true, type: "string" },
output: { type: "object" },
"output.annotations": { type: "object[]" },
"output.annotations[].annotation_level": {
enum: ["notice", "warning", "failure"],
required: true,
type: "string"
},
"output.annotations[].end_column": { type: "integer" },
"output.annotations[].end_line": { required: true, type: "integer" },
"output.annotations[].message": { required: true, type: "string" },
"output.annotations[].path": { required: true, type: "string" },
"output.annotations[].raw_details": { type: "string" },
"output.annotations[].start_column": { type: "integer" },
"output.annotations[].start_line": { required: true, type: "integer" },
"output.annotations[].title": { type: "string" },
"output.images": { type: "object[]" },
"output.images[].alt": { required: true, type: "string" },
"output.images[].caption": { type: "string" },
"output.images[].image_url": { required: true, type: "string" },
"output.summary": { required: true, type: "string" },
"output.text": { type: "string" },
"output.title": { required: true, type: "string" },
owner: { required: true, type: "string" },
repo: { required: true, type: "string" },
started_at: { type: "string" },
status: { enum: ["queued", "in_progress", "completed"], type: "string" }
},
url: "/repos/
}
}
}
Начиная с v17, определение того же метода выглядит следующим образом :
{
checks: {
create: [
"POST /repos/{owner}/{repo}/check-runs",
{ mediaType: { previews: ["antiope"] } },
];
}
}
В конце, ранее извлеченный код был собран в обещанные 10 строк:
import { Octokit as Core } from "@octokit/core";
import { requestLog } from "@octokit/plugin-request-log";
import { paginateRest } from "@octokit/plugin-paginate-rest";
import { restEndpointMethods } from "@octokit/plugin-rest-endpoint-methods";
import { VERSION } from "./version";
export const Octokit = Core.plugin([
requestLog,
paginateRest,
restEndpointMethods,
]).defaults({ userAgent: `octokit-rest.js/${VERSION}` });
Тесты
Каждая строка кода была изменена между версиями v16 и v17, поэтому единственный способ убедиться в отсутствии новых ошибок — провести полное тестирование.
На момент создания модуля в 2017 году у нас не было никаких тестов, но были
You must be registered for see links
. Первым делом я превратил их в интеграционные тесты, а поскольку JavaScript Octokit SDK задумывался как основа SDK для всех популярных языков, я создал
You must be registered for see links
— независимый от языка, автоматически обновляемый набор макетов http для общих случаев использования.Для оставшейся логики, специфичной для @octokit/rest, были написаны интеграционные тесты для 100% покрытия. На сегодняшний момент, если значение опустится ниже 100% тесты упадут.
Прим. переводчика:
You must be registered for see links
Работая над переходом на 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.
В конце, я хотел бы сказать спасибо
You must be registered for see links
,
You must be registered for see links
и
You must be registered for see links
, которые создали и поддерживали модуль github до того, как он превратился в @octokit/rest.