Comments 32
Любопытно, почему в качестве решения предлагается «лёгкий swagger», а не переход в надсистему, например, через GraphQL?
Собственно в этом и был мой вопрос — зачем использовать «ещё один стандарт документации», если можно попробовать решить проблему шире? В общем-то, в такой постановке он довольно риторический…
«GraphQL лучше REST»?
для того что бы не скатываться в религиозную дискуссию достаточно признать очень простой факт — и то и то — RPC over http. Просто в одном случае есть конкретика (формат, протокол если хотите) а во втором — его нет. То есть в целом решая те же проблемы что решает graphql (удобная композиция данных для клиента) вы переизобретете оный (возможно в более приятном для вас виде). Как пример — json api в целом еще в версии 1.0 предлагал очень похожие плюшки, просто масштабы были не те и приоритеты другие.
OpenAPI, Swagger и т.д. — это лишь попытка формализовать описание контрактов. Причем ни graphql ни сваггер в этом плане не являются универсальными решениями. Вопрос гибкости и расширяемости стандарта. Сваггер скажем упирается в ограничения спецификации json schema, в то время как graphql имеет мягко скажем примитивную систему типов, которая на хоть сколько нибудь серьезном проекте обрастает кучей кастылей.
Чет меня понесло… Короче суть — ограничивать себя выбором одного из двух — это глупо.
У OpenAPI есть серьёзный недостаток — сложность структуры и, зачастую, избыточность. Для небольшого проекта содержимое JSON-файла спецификации может быстро разрастись до нескольких тысяч строк. В таком виде поддерживать этот файл вручную невозможно. Это — серьёзная угроза для самой идеи поддержания актуальной спецификации по мере развития API.
Просто этот файл должен генерироваться автоматически.
Вместо создания нового стандарта «который проще вручную редактировать».
И это вы ещё до версионирования не добрались.
Генерироваться из чего? Если имеется ввиду сам код, то на практике это вряд ли реализуемо, учитывая возможную специфику реализации компонентов (роутов, экшнов и т.п.), а также всё множество различных технологий и фреймворков.
Вообще первичной должна быть все же спецификация, которая затем «имплементируется» в виде кода.
А какие проблемы вы видите с версионированием? В нескольких реальных проектах в течение продолжительного времени используем этот подход без каких-либо проблем.
На моём прошлом месте работы описание АПИ в формате сваггера успешно генерируется при деплое и развёртывании приложения (Java + Spring). Доп. инфа описывается через аннотации.
Да, такое не для каждого языка/фреймворка есть, но для большинства популярных вполне.
Но представьте, что у вас в проекте есть пять команд: бэкенд, фронтэнд, виндоус-десктоп, андроид-мобайл и эппл-мобайл. Через два месяца вам надо синхронно обновить версию приложения для всех платформ. В этой ситуации бэкенд уже не может что-то там писать-писать у себя внутри, а потом выкатить всё скопом. Или выкладывать потихоньку, постоянно что-то изменяя и добавляя. Их за это просто будут бить.
В таких случаях гораздо лучше работает подход documentation first. Все заинтересованные стороны сообща разрабатывают спецификацию API в понятном всем формате (swagger, openAPI), утверждают её и только потом приступают к разработке.
Генерироваться из чего? Если имеется ввиду сам код, то на практике это вряд ли реализуемо
А это зависит от выбранных инструментов/языка программирования.
Я пишу под .Net, для автогенерации есть либа, подключить — несколько строчек.
Для Java и Php наверняка тоже есть аналоги, reflection api ведь у них есть.
Для Js, ну да, тяжелый случай, есть нет Typescript.
А какие проблемы вы видите с версионированием?
Большое количество версий, распухание спецификации. Исходная проблема ведь так и обозначена «спецификации может быстро разрастись до нескольких тысяч строк. В таком виде поддерживать этот файл вручную невозможно.»
Большого количества версий быть не должно. В общем случае оно должно соответствовать количеству доступных для пользателей версий API, и обычно их не так много: например, stable
и prestable
. Хранятся эти версии обычно в разных ветках, так что сложностей не возникает.
Хранятся эти версии обычно в разных ветках
Это как? У вас в проде постоянно несколько бранчей задеплоено? Серьезно?
и обычно их не так много: например, stable и prestable.
Странное название версий. И что вы делаете с клиентами, которые используют stable и вы хотите ваш prestable сделать stable?
Именно поэтому как раз очень важно нахождение спецификации рядом с кодом и совместное версионирование, вкупе с CI.
В типизированных языках схема, документация, и валидация, генерится из классов в коде. Забавно какое изврат надо в ноде, чтобы получить то, что на нормальных платформах само собой разумеется.
Вот абсолютно согласен.
Претензия не к самой статье, а в целом было огромным удивлением узнать:
Заканчивается 2018 год, а фанаты "прогрессивных" языков до сих пор учатся генерировать WSDL/OpenAPI/ из метаданных сборки/кода.
Исходное состояние:
— продукты средней сложности
— API прежде всего для поддержки работы SPA и мобильных приложений, но также есть и межсервисное взаимодействие
— подход к разработке во многом выработался в духе «API-first» — API целенаправленно пишется постановщиками чуть ли не в первую очередь, согласовывается потребителями и нужен чуть ли не всем участникам: менеджерам, аналитикам, разработчикам, тестировщикам и иногда даже заказчикам или сторонним подрядчикам.
Долгое время всё это велось в confluence с не строгим шаблоном. Это вызывало следующее проблемы:
1. Отсутствие регламента и прозрачности в изменениях. Хотя круг тех, кто имел право внесения правок был ограничен, но всё же их было сложно контроллировать. Из-за этого возникали проблемы в духе «зачем вы это поменяли?», «а я не знал?», «в рамках чего было это изменение?» и прочее.
2. Отсутствие формализации описания там, где она была бы полезна. Достаточные ограничения на типы полей, примеры, единообразность, наглядность — всего этого часто не хватало. Легко можно было обнаружить, например, поле даты где-то в виде UNIX timestamp, а где-то в виде ISO8601 в одном и том же контексте.
3. Сложность использования для валидации или тестирования. Во многом вытекает из первых двух пунктов и обычных людских ошибок. Даже если каждый метод снабжался JSON-схемой и примерами запросов и ответов, то это не гарантировало того, что они актуальные и вообще правильные.
В качестве эксперимента разработчики начали использовать Blueprint API для описания сначала межсерверного взаимодействия. Зачастую там не было медиаторов в лице аналитиков, поэтому чтобы договариваться между собой они писали спеку в этом формате и шарили между собой. Позднее под доработку инструментария были выделены ресурсы и был эксперимент по попытке полноценного использования Blueprint API с самого начала нового проекта.
Как это выглядело.
По сути был почти полностью перенят процесс работы разработчиков и применён к работе аналитика над API. Основные моменты:
— Любое изменение только по задаче в Jira. К этому не надо относиться как к лишней бюрократии — это просто момент инициации работы. Даже какое-то подробное объяснение не требуется.
— Всё API — в git. Любое изменение проводится близко к git flow — именование веток, пулреквесты, мерджи в нужные ветки.
— В пулреквест в качестве ревьюверов доабвляются все заинтересованные лица со стороны разработки. После обсуждения, правок и апрувов ветка может быть смержена, а изменение в апи опубликовано.
— Весь тулчейн настроен в CI и работа аналитика сведена только к текстовому редактору и git'у.
Какие плюсы поимели:
— Процесс работы над API стал формализованным и прозрачным для всех.
— Blueprint предоставил достаточные средства для формализации описания. Да, он не идеальный и многих вещей в нём не хватает, а что-то было сделано криво. Но уже через несколько итераций выстроилась достаточно удобная схема ведения спецификации, организации файлов, соглашений по именованию сущностей внутри Blueprint API. Какие-то фичи были добавлены нами, какие-то баги поправлены.
— Минимизация ошибок из-за человеческого фактора. За счёт переиспользования сущностей внутри спецификации и автоматической генерации примеров, JSON-схемы и табличного описания полей, аналитик получал по сути конструктор методов, на выходе которого получалось удобное для всех заинтересованных лиц представление.
— Автоматизация и валидация. Тут очевидные применения всего этого добра — автогенерация интерфейсов к API (прежде всего у мобильщиков), валидация ответов при тестировании и прочее.
Какие проблемы возникли:
— Git flow это не только благо. Всё же документация это не код. В документации много изменяемых, но не формализуемых частей — текстовые описания методов, тексты ошибок, таблицы прав и прочее.
— Сложности синхронизации с командой и процессами разработки. Зачастую документация писалась сильно вперёд. Аналитик мог описывать функциональность на 1 и 2 релиза вперёд, а значит накидывать в git ветки, которые могли не скоро понадобится. А если в это вмешивались изъяны процесса разработки, то даже порядок будущего мерджа ветвей нельзя было предсказать. Вкупе с первым пунктом это вытекало либо в трудности при мердже (конфликты, cherry-picking, вот это всё), либо в сложности с определением какая часть документации актуальна, а какая уже ускакала вперёд.
— Повышенный overhead на работу аналитика. Раньше он просто редактировал страничку в confluence, а теперь он ломает голову над декомпозицией структур в Blueprint API, над ветками, пулреквестами и прочим. Можно сказать, что это повышает нижнюю планку для аналитика в проекте.
— Организационные моменты. Просмотр PR'ов по документации было правом, но не обязанностью заинтересованных лиц. Они тратили на это время, но это время не было их должностной обязанностью. В итоге со временем многие начали забивать на ревью.
— Ограничения Blueprint API. Да, многого не хватает. Да, редко, но были ситуации, когда API подстраивалось под возможности документирования хотелки. Да, это куча разрозненных файлов (в лучшем случае — насколько я знаю, в Swagger'е это просто диких размеров yaml), скреплённых придуманными вами соглашениями и правилами.
По итогам почти года использования этой штуки (ах да, я как раз в роли аналитика выступал) на проекте «с нуля» и до «n+1-ого релиза», могу сказать, что это был положительный опыт. Да, многое было сделано неудобно, но процесс создания и ведения API встал на некие рельсы, стал более выделенным. И все потребители оказались удовлетворены — менеджеры получили человечное и красивое опсиание, тестировщики получили почти исчерпывающие данные об ограничениях API, разработчики получили предсказуемость, полноту и возможность накручивания новых тулз поверх формального описания Blueprint API.
Да, это куча разрозненных файлов (в лучшем случае — насколько я знаю, в Swagger'е это просто диких размеров yaml)
Можно разбить спеку на части и ссылаться друг на друга через $ref-ы. Или это не помогает?
В Blueprint API для этого есть что-то вроде «наследования» и «переопределения полей» и возможность инклудить одни документы в другие (но эта фича не из коробки). Если добавить соглашений наименования и разбиения на файлы, то в целом становится удобоваримо.
Но да, соглашения наименования и разбиения всё равно нужны.
Удобнее всего писать unit-тесты не для отдельных классов, моделей и контроллеров, а для конкретных эндпоинтов.
Вы путаете unit-тесты и интеграционные тесты. Они должны не заменять друг друга, а дополнять.
У OpenAPI есть серьёзный недостаток — сложность структуры
Как уже заметили выше, обычно swagger-схема генерируется автоматически. Т.ч. к недостаткам это можно отнести с натяжкой
У OpenAPI есть серьёзный недостаток — сложность структуры и, зачастую, избыточность. Для небольшого проекта содержимое JSON-файла спецификации может быстро разрастись до нескольких тысяч строк. В таком виде поддерживать этот файл вручную невозможно. Это — серьёзная угроза для самой идеи поддержания актуальной спецификации по мере развития API.
Не обязательно держать все в одном большом JSON-файле, можно же разбить как например здесь: github.com/Rebilly/RebillyAPI/tree/master/spec
+ использование YAML вместо JSON улучшает «сапортабилити» в разы.
К сожалению, вышедшая год назад OpenAPI 3.0 всё ещё мало поддерживается и мне не удалось найти достойных примеров документации на её основе
Поначалу да, но сейчас в Swagger UI уже таки поддерживается большинство возможностей OpenAPI 3.0.
5+1 случай, когда спецификация REST API играет огромную роль