Значит к делу. У нас в Хекслете немало разных интеграций внутри кода, начиная от управления docker на других машинах (для практик), до создания заявок в AmoCRM. И для многих из них нам приходится писать небольшие (а иногда большие) обертки над их апишкой, потому что sdk для их сервисов либо нет, либо они устарели. А иногда sdk есть, но только для одного-двух языков. Короче беда, особенно этим страдают русскоязычные сервисы, где даже дока по api какой-то колхоз где все примеры на php. Я понимаю почему так было изначально, когда весь рунет был на пыхе, но елки палки, с тех пор десяток лет прошел.
На выходных психанул и решил покончить с этим. План был прост, закидываем доку в codex и просим на его основе составить typespec, который потом генерирует openapi спеку, которую я потом закидываю в какой-нибудь генератор sdk. Быстрое гугление показало, что есть опенсорсный генератор с поддержкой ruby, но он не делал типизацию (в ruby Sorbet) поэтому продолжил поиски и нашел сервис stainless, с которым забегая вперед все получилось.
Почему не сразу openapi? Typespec это продукт майкрософта. Он позволяет описывать openapi спеку на языке похожем на ts, с линтерами, компилятором и вот этим всем. Затем все это добро можно превратить не только в openapi спеку, но и сразу из него сделать готовые библиотеки. К сожалению ruby пока там нет, поэтому вместо простого typespec => sdk, получилась схема typespec => openapi => stainless.
Начал я с AmoCRM, в котором размер апи мама не горюй. Причем дока местами неточная, поэтому я добавил туда единственную официальную sdk на PHP. Закинул это все в codex и попросил собрать typespec. Суммарно весь процесс занял около часа и на выходе я получил тысячи строк (выходной openapi spec >8 000 строк). Все это лежит в отдельной репе, через которую генерируются sdk.
Дальше потратил какое-то время на разобраться со stainless, у них довольно интересная схема того как генерятся эти sdk. Начиная от конфига и утилиты командной строки, заканчивая схемой репозиториев под sdk веток внутри и процесса релиза. Мое почтение тем кто это придумал. В сухом остатке, там надо указать sdk под какие языки сделать, дальше под каждый sdk делается свой репозиторий, куда stainless уже пулреквестами присылает обновления-релизы, которые собираются при изменении спеки openapi.
require "bundler/setup"
require "amocrm"
amocrm = Amocrm::Client.new(
token: ENV["AMOCRM_AUTH_TOKEN"], # This is the default and can be omitted
subdomain: "My-Subdomain"
)
response = amocrm.unsorted_leads.create_forms(
body: [{metadata: {}, source_name: "source_name", source_uid: "source_uid"}]
)
puts(response)
Весь процесс шел гладко примерно до этого момента, но когда я уже начал использовать библиотеку, выяснилось, что там есть баг. Для части запросов AmoCRM возвращал application+hal/json чем ломал логику сгенерированной sdk. Агент раскопал, что там был неправильный регексп и сразу его пофиксил пулреквестом в sdk. Ну и чо бы не сказать ребятам о проблеме подумал я и прямо из интерфейса stainless отправил им багрепорт. Какого же было мое удивление, когда на следующий день их бот прислал пулреквест в мою sdk с эти исправлением, но уже официально.
В общем мне это так понравилось, что я решил повторить этот трюк с кучкой других сервисов. И теперь у меня есть openapi схема и sdk для cloudpayments, docker, yoomoney.
Все это открыто и лежит на гитхабе. Можно брать не только готовые sdk, но и спеки.
либа https://github.com/Hexlet/amocrm-ruby
спека https://github.com/Hexlet/amocrm-api
p.s. Если кто знает ребята из этих сервисов, киньте им, пусть заберут себе и выложат на сайте чтоли :)
Telegram | YouTube | Сообщество