Zero-dependency SDK, open-source и партнёрский API
TL;DR: один SDK с 14 транзитивными зависимостями отрезает половину интеграторов ещё на `composer require`, а закрытый репозиторий — на security-ревью покупателя. Разбираем три инженерных решения, которые превращают публичный API в платформу: zero-dependency SDK на stdlib, открытый исходный код на `github.com/BOTIX-pro/*` и партнёрский слой с sub-проектами и жёсткой изоляцией данных. Факты — по реальному Public API v1 BOTIX, секреты замаскированы.
Коротко
- Zero-dependency SDK — не про красоту, а про риск. Три SDK BOTIX (PHP, Python, Node) собраны только на stdlib:
composer audit/npm audit/safety checkзелёные по дизайну, а не по везению. - Open-source снимает главный блокер корпоративной сделки: security проходит SDK за час по GitHub вместо двух недель NDA, а баг чинится через PR, а не через тикет.
- Партнёрский слой — это не отдельный продукт, а набор архитектурных свойств (отдельный тип ключа, sub-проекты,
Auth::assertProjectAccess(), отдельный набор эндпоинтов), которые закладываются заранее, иначе изоляция данных потечёт на первой ошибке.
Три решения из заголовка не связаны техническим стеком, но связаны одной задачей: снять трение на входе для того, кто ставит ваш код себе в продакшен. Ниже — каждое отдельно: суть, конкретика по Public API v1 BOTIX и разбор границ, где решение работает, а где нет.
BOTIX — российская платформа AI-ассистентов для бизнеса. Public API v1 в проде на api.botix.pro/public/v1/*, документация (Redoc) — на developers.botix.pro, три открытых SDK (PHP, Python, Node), CLI и example-приложения (Laravel, Express, Flask) — в организации github.com/BOTIX-pro.
Zero-dependency SDK: почему 14 зависимостей — это чужой техдолг
Команда подключает сторонний API. Видит composer require botix-pro/sdk (или pip install, или npm install), ставит. Через минуту в composer.lock появляется не одна новая строка, а пятнадцать: SDK притащил HTTP-клиент, JSON-валидатор, библиотеку для UUID, retry-механизм, ещё один логгер и пару утилитарных пакетов, которые поддерживает один мейнтейнер в свободное время.
Каждая транзитивная зависимость создаёт ровно три класса проблем:
- Конфликты версий. SDK тянет
requests==2.28.0, у интегратора уже стоитrequests==2.31.0из-за собственного фреймворка. Жёсткий pin — установка падает с конфликтом. Мягкий (>=2.20,<3.0) — встанет одна из совместимых версий, и обновление фреймворка через полгода сломает совместимость. В Python это особенно болезненно: глобальное пространство имён не позволяет держать две версииrequestsодновременно. В Node за счётnode_modulesper-package чуть легче, но дубли раздувают бандл. - Supply-chain атаки. Каждая транзитивная зависимость — потенциальный вектор:
event-stream(доступ передан незнакомцу, добавившему кражу кошельков),ua-parser-js(взлом аккаунта мейнтейнера, майнер в релизе),colors.js(протест-релиз, ломающий всё зависимое). Когда SDK тянет 14 зависимостей, число транзитивных пакетов в дереве переваливает за 100 — иnpm audit/safety checkрегулярно ругаются на advisories в зависимостях зависимостей, которые интегратор пофиксить не может: он не контролирует SDK. - Устаревание. Зависимости стареют. Свежая год назад сегодня имеет известную уязвимость. SDK с заброшенными зависимостями — мина под интегратором.
Наше решение — zero-dependency: SDK использует только стандартную библиотеку языка и ничего больше. Никаких requests, axios, guzzlehttp/guzzle. В PHP — curl через ext-curl (входит в стандартную поставку). В Python — urllib.request из stdlib. В Node — встроенные https и http.
Полный composer.json PHP-SDK без сокращений — на github.com/BOTIX-pro/sdk-php/blob/main/composer.json:
{
"name": "botix-pro/sdk",
"description": "Official BOTIX SDK for PHP",
"type": "library",
"license": "MIT",
"require": {
"php": "^8.2",
"ext-curl": "*",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^10.5",
"phpstan/phpstan": "^1.10"
},
"autoload": {
"psr-4": {
"Botix\\": "src/"
}
}
}Секция require — нулевая (только сам PHP и встроенные расширения). У Python-SDK requirements.txt пустой, у Node-SDK секция dependencies в package.json нулевая (только devDependencies для билд-инструментов, которые в продакшен не попадают). Для сравнения: типичный SDK другого вендора — 14 строк в require, 47 транзитивных зависимостей в дереве, 12 advisories в composer audit после года жизни.
Возражение «но requests удобнее urllib, зачем городить с stdlib» справедливо для прикладного кода. SDK — не прикладной код. Он живёт у интегратора в продакшене, и его задача — не быть красивым, а минимизировать риск для того, кто его установит.
Технически zero-dependency несложно: HTTP-клиент в stdlib покрывает 95% сценариев (GET/POST/PUT/DELETE, заголовки, тело, чтение ответа); HTTP/2 multiplexing и connection pooling публичному API через интернет не нужны. JSON-сериализация есть везде из коробки, UUID — тоже (или 10 строк кода), retry — цикл с экспоненциальным бэкоффом на полчаса работы. Сложнее становится тестирование (моки HTTP через урезанный stdlib-клиент пишутся вручную) — это решается тем, что все три SDK генерируются openapi-generator-cli из единого openapi.yaml, шаблоны настроены один раз, и сгенерированный код идентичен по структуре во всех трёх языках. Про генератор и white-label подробнее — в разборе SDK из OpenAPI: генератор, white-label, open-source.
Как проверить SDK перед установкой
Быстрая эвристика — открыть package.json / composer.json / setup.py на GitHub и посмотреть размер секции зависимостей:
- 0–2 пакета — SDK с уважением к интегратору.
- 5–7 — приемлемо, но проверьте, что зависимости мейнстрим, а не маргинальные пакеты от одного автора.
- 10+ — SDK, который кладёт на вас груз поддержки чужой экосистемы.
Установка zero-dependency SDK перестаёт быть событием в логе CI/CD: одна строка, одна папка, никаких конфликтов. Размер бандла Node-приложения после @botix/sdk растёт на 30–40 КБ, а не на 2 МБ.
Open-source SDK: пять функций, а не «щедрость»
Вопрос «открывать ли исходники SDK» в большинстве команд обсуждают через категорию щедрости: «принесём пользу сообществу» против «лучше потратим время на фичи». В таком виде спор не приходит к решению — обе стороны рассуждают о морали, а не о бизнесе. На деле open-source SDK — инструмент с конкретными функциями, каждую из которых стоит считать отдельно.
Функция первая: security-аудит без участия поставщика. Корпоративная интеграция почти всегда проходит через security-команду. Закрытый SDK для них — чёрный ящик, который что-то делает с данными. Дальше три варианта, все дорогие: заблокировать интеграцию (частый исход); потребовать SOC 2 Type II, ISO 27001 и DPA (месяцы и десятки тысяч долларов); попросить исходники под NDA (две недели ожидания). Open-source закрывает их одним движением: security открывает GitHub, видит, что библиотека делает только заявленное, и пропускает. SOC 2 всё равно нужен — для инфраструктуры и процессов, но SDK как точка входа в чужой код становится прозрачным. SDK на github.com/BOTIX-pro/sdk-php (Composer-пакет botix-pro/sdk, тег v1.1.0) проходит проверку покупателя за час вместо двух недель — ещё до того, как мы получаем сигнал, что нами интересуются. Корпоративный sales-цикл сокращается на месяцы.
Функция вторая: bug fix не блокируется вендором. В закрытом SDK любая ошибка — тикет в поддержку и новая версия через месяц-три. В open-source два варианта: сам сделать PR либо временно форкнуть и патчить через VCS-ссылку в composer.json/package.json, пока upstream не примет фикс. Никакой блокировки. На стороне поставщика это переводит багфиксы в режим «принять PR» вместо «диагностировать и исправлять самим».
Функция третья: сигнал зрелости API. Открытая лицензия — сигнал, что у API есть стабильный контракт, который не стыдно показать. Закрытый SDK читается как «наколхозили, поэтому прячут». Три SDK BOTIX имеют одинаковую структуру методов и синхронные мажорные версии:
composer require botix-pro/sdk:^1.1
pip install botix==1.1.0
npm install @botix/sdk@1.1.0Если разработчик переключается между языками, переучиваться не нужно — структура client.contacts.create(...) одинакова в PHP, Python и Node. Все три генерируются openapi-generator-cli из единого openapi.yaml — машинно-читаемой точки правды.
Функция четвёртая: контрибьюции от сообщества. На ранних этапах open-source SDK — односторонняя отдача. По мере роста появляются PR с типичными улучшениями (retry, timeout, прокси, совместимость с нетипичной версией). У зрелых поставщиков (Stripe, Twilio, Slack) — десятки внешних контрибьюторов. SDK BOTIX молодые, контрибьюций пока нет — оценка делается через 90 дней после релиза, это нормальный начальный режим.
Функция пятая: white-label-партнёры конвертируют наш SDK в свой. Партнёр — агентство или ISV — почти всегда требует исходники интегрируемых библиотек, иначе его security не пропустит встраивание в собственный продукт. С закрытым SDK у партнёра выбор: ждать NDA (пара недель) или уйти к конкуренту с открытым кодом. MIT-лицензия снимает вопрос: партнёр кладёт LICENSE в свой бандл, упоминает BOTIX в about-секции и встраивает SDK под своим брендом. Это прямой мост к следующему разделу — про архитектуру партнёрского слоя, которую мы разбираем отдельно в Зачем открывать SDK в open-source: 5 причин.
Сколько open-source стоит поставщику
Главный страх — что код «утащат». Утащить SDK без потери смысла невозможно: он бесполезен без API, к которому обращается; под чужой API переписать легче, чем переиспользовать. Второй страх — раскрытие архитектуры — решается дисциплиной: SDK не содержит бизнес-логики, он делает три вещи (формирует запрос, подписывает, парсит ответ), всё остальное — на стороне API. Открытый код тогда не раскрывает ничего сверх того, что и так лежит в OpenAPI-спецификации. Третий страх — поддержка: публичный репозиторий означает входящие issues, и без выделенного человека open-source SDK превращается в кладбище с просрочкой по 200 дней. У нас на это выделен один разработчик с 20–25% времени, около 50 человеко-часов в квартал.
Итог по трудозатратам: около 60 человеко-часов в месяц на три SDK + CLI + три example-приложения, плюс CI-матрица (4 версии PHP × 2 Python × 2 Node) и одноразовые публикационные ключи пакетных менеджеров (после использования отзываются — требование безопасности). Альтернатива — senior sales-инженер за 250–400 тысяч рублей в месяц. Открытый SDK стоит примерно столько же, но работает пассивным каналом доверия 24/7.
Когда open-source SDK не нужен
- API нишевой, аудитория два-три интегратора, все по NDA — открывать ради абстрактной зрелости бессмысленно.
- API в стадии активного breaking-change — сообщество увидит нестабильность в публичном репозитории, сигнал обратный ожидаемому.
- Нет человека на review PR и ответы на issues — открытие ухудшит ситуацию.
Все три условия — про ранние стадии. Когда продукт зреет, API стабилизируется и ресурс появляется — открытие становится логичным шагом. В нашем случае все три были закрыты до публикации.
Что превращает API в платформу: партнёрский слой
Один эндпоинт /contacts не делает API платформой. Платформа начинается там, где появляется второй уровень: партнёр, встраивающий API внутрь своего продукта и продающий его дальше. У прямого клиента контур простой — один аккаунт, один проект, несколько ключей, один webhook. У партнёра он многоуровневый: сам партнёр имеет аккаунт у поставщика, внутри — десятки конечных клиентов, у каждого свой логический проект со своими данными, биллингом, webhook'ом и настройками.
Если удовлетворять партнёрскую модель тем же API, что и обычных клиентов, быстро упираешься в несовместимости: обычный ключ работает в контексте одного проекта, партнёрский — должен работать в контексте партнёрского аккаунта и переключаться между конечными. Минимальный набор свойств, который для этого закладывается:
- Партнёрский уровень аутентификации. Отдельный тип ключа (partner key) с более высокими привилегиями, чем у обычного project key: создать проект, перечислить существующие, получить ключи. Обращение к партнёрским операциям с обычным ключом —
403. - Sub-проекты под одним партнёрским аккаунтом. Иерархия «партнёр сверху, конечные проекты снизу», каждый sub-проект — со своими данными, webhook'ом, биллингом.
- OAuth installations с реселлерскими scope. Partner-scope позволяет OAuth-приложению, установленному в партнёрский аккаунт, видеть все sub-проекты, а не только тот, куда оно установлено напрямую.
- Биллинг-события через API. Партнёр биллит по своей модели, ему нужны сырые данные (запросы, сообщения, активные контакты по каждому sub-проекту за период) — либо эндпоинт типа
GET /partner/usage, либо webhook в конце расчётного периода. - Audit-логи на партнёрском уровне. Когда конечный клиент пишет «не работает», партнёр должен диагностировать сам, без поставщика — по журналу sub-проектов, регулируемому тем же partner-ключом.
- Кастомные домены и брендирование. Сам API кастомного домена не требует, но если в партнёрском решении есть UI под брендом партнёра — нужны white-label-домены. В BOTIX этот пункт пока в плане; текущая партнёрская работа идёт через API без кастомного фронтенда.
Ключевая граница — изоляция данных. Внутри одного партнёрского аккаунта могут быть sub-проекты конкурирующих компаний, и возможность одного увидеть данные другого — катастрофа. Граница держится на трёх уровнях: на уровне БД — WHERE project_id = ? в каждом запросе; на уровне API — явный project_id и проверка принадлежности партнёрскому аккаунту; на уровне ключей — ответ по чужому sub-проекту по чужому ключу невозможен. В BOTIX это Auth::assertProjectAccess($projectId) в начале каждого эндпоинта, работающего с проектом (при попытке достать чужой ресурс возвращается 404, а не 403 — не утекает даже факт существования объекта). Партнёрский уровень добавляет слой: проверяется не только доступ к sub-проекту, но и что он принадлежит партнёрскому аккаунту, выпустившему ключ. Как та же изоляция multi-tenant выглядит с точки зрения OAuth и webhook — в разборе Партнёрский API: sub-проекты, изоляция и OAuth-scope.
Документация для партнёра — отдельная: в репозиториях botix-pro на GitHub это Postman/Bruno-коллекция с разделом «Partner API» (создание sub-проекта, получение ключа, перечисление проектов, выгрузка usage) — отдельный набор операций, не подмножество обычной коллекции.
Чек-лист готовности к партнёрской работе
Готовность оценивается за полчаса по короткому списку:
- Есть отдельный тип ключа с расширенными правами?
- Есть концепция sub-проектов?
WHERE project_id = ?в каждом запросе?Auth::assertProjectAccess()в начале каждого эндпоинта?- Отдельные scope для партнёров в OAuth?
- Способ получить сырые usage-данные через API?
- Аудит-журнал, доступный партнёру по всем sub-проектам?
- Отдельная документация и Postman-коллекция?
Если «нет» начинается с третьего пункта — API технически не готов к партнёрам. Если «да» на все — открывать можно без страха получить инцидент на первой неделе. Решение о партнёрском слое продуктовое, не техническое: не каждый API должен быть платформой. Но если решение принято, свойства закладываются с самого начала, а не на третьей итерации после первых жалоб.
Что не делать
- Не навешивать партнёрские возможности на обычные эндпоинты через флаги «если ты партнёр, можешь передать ещё этот параметр» — запутанная семантика. Лучше отдельный префикс
/partner/v1/*. - Не делать партнёрский API «по запросу» избранным по NDA. Работает, пока партнёров три; на двадцати — разные обещания, теневая документация, техдолг.
- Не ставить высокий порог входа. На старте партнёрский слой — маленькие команды, экспериментирующие; из них и вырастают крупные.
Что это значит для интегратора
- Исходники SDK открыты на
github.com/BOTIX-pro— security-проверка занимает час, не недели. - Zero-dependency —
composer audit,npm audit,safety checkпоказывают чистый статус по дизайну. - Один и тот же SDK API в трёх языках — миграция стека не требует переучивания.
- Нашли баг — можно сделать PR; торопитесь — форк и патч через VCS-ссылку, без блокировки через тикет.
- Строите продукт поверх BOTIX для своих клиентов — партнёрский слой (sub-проекты, изоляция, отдельная коллекция) закладывается заранее, а не докручивается после первого инцидента.
Попробуйте API BOTIX
Получите ключ, отправьте первый запрос и поймайте webhook — прямо в браузере, без боевого канала.
Попробовать API бесплатноЧитайте также
API как платформа: multi-tenant, white-label и open SDK
Генерация SDK из OpenAPI, white-label и open-source
Как публичный API становится платформой для интеграторов
Версии SDK и semver: как выпускать обновления, не ломая партнёрские интеграции
