Pull to refresh

Comments 32

[картинка про 14 конкурирующих стандартов]

Любопытно, почему в качестве решения предлагается «лёгкий swagger», а не переход в надсистему, например, через GraphQL?
Смотря, о какой проблеме вы говорите. О том, что Swagger сложный или о том что «GraphQL лучше REST»? Во втором случае, боюсь, мы скатимся к очередной религиозной дискуссии, чего бы не хотелось.
Второе суждение сложно назвать истинным, ибо «лучше» в любом случае субъективно. Я скорее о том, что и OpenAPI и tinyspec являются тулзами для документации и многие аспекты, которые можно использовать для разработки эндпоинтов (валидация данные, написание тестов в вашем случае), являются следствием скорее строгого стандарта, чем артефактом самой технологии. В этом плане, по моему мнению, GraphQL предлагает эти аспекты как часть парадигмы, во многом даже объединяя в себе REST API, валидации, связывание данных и документацию всего этого дела. Опять же в силу строгости стандарта к нему также применимы различные свистелки и кряхтелки вроде быстрого написания тестов.

Собственно в этом и был мой вопрос — зачем использовать «ещё один стандарт документации», если можно попробовать решить проблему шире? В общем-то, в такой постановке он довольно риторический…
«GraphQL лучше REST»?

для того что бы не скатываться в религиозную дискуссию достаточно признать очень простой факт — и то и то — RPC over http. Просто в одном случае есть конкретика (формат, протокол если хотите) а во втором — его нет. То есть в целом решая те же проблемы что решает graphql (удобная композиция данных для клиента) вы переизобретете оный (возможно в более приятном для вас виде). Как пример — json api в целом еще в версии 1.0 предлагал очень похожие плюшки, просто масштабы были не те и приоритеты другие.


OpenAPI, Swagger и т.д. — это лишь попытка формализовать описание контрактов. Причем ни graphql ни сваггер в этом плане не являются универсальными решениями. Вопрос гибкости и расширяемости стандарта. Сваггер скажем упирается в ограничения спецификации json schema, в то время как graphql имеет мягко скажем примитивную систему типов, которая на хоть сколько нибудь серьезном проекте обрастает кучей кастылей.


Чет меня понесло… Короче суть — ограничивать себя выбором одного из двух — это глупо.

UFO just landed and posted this here
У 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?
Это был абстрактный пример. Всё сильно зависит от конкретной задачи и многих факторов, например, публичный ли это API или внутренний. Разные версии могут быть определены ветками или тегами, это не принципиально. Prestable это чаще всего не «прод», а staging. В каких-то случаях это может быть alpha или beta. Стратегии релизов и поддержки обратной совместимости также специфичны для разных проектов.

Именно поэтому как раз очень важно нахождение спецификации рядом с кодом и совместное версионирование, вкупе с CI.

В типизированных языках схема, документация, и валидация, генерится из классов в коде. Забавно какое изврат надо в ноде, чтобы получить то, что на нормальных платформах само собой разумеется.

Вот абсолютно согласен.
Претензия не к самой статье, а в целом было огромным удивлением узнать:
Заканчивается 2018 год, а фанаты "прогрессивных" языков до сих пор учатся генерировать WSDL/OpenAPI/ из метаданных сборки/кода.

Поделюсь опытом использование таких тулз, а точнее Blueprint API.

Исходное состояние:
— продукты средней сложности
— 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-ы. Или это не помогает?
Поддержу. Сам пользуюсь пакетом multi-file-swagger. Там в самом начале ссылка на статью с примером использования.
Я сваггер только мельком смотрел. Может какие-то расширения к нему позволяют разбивать на части спеку.
В Blueprint API для этого есть что-то вроде «наследования» и «переопределения полей» и возможность инклудить одни документы в другие (но эта фича не из коробки). Если добавить соглашений наименования и разбиения на файлы, то в целом становится удобоваримо.
Все что угодно вместо того чтобы генерировать документацию в тестах.
Удобнее всего писать unit-тесты не для отдельных классов, моделей и контроллеров, а для конкретных эндпоинтов.

Вы путаете unit-тесты и интеграционные тесты. Они должны не заменять друг друга, а дополнять.
У OpenAPI есть серьёзный недостаток — сложность структуры

Как уже заметили выше, обычно swagger-схема генерируется автоматически. Т.ч. к недостаткам это можно отнести с натяжкой
За 3 года работы со swagger мне он все еще нравится. Конечно решает генерация библиотеки из схемы. В основном пользовался готовой схемой к проекту.
У OpenAPI есть серьёзный недостаток — сложность структуры и, зачастую, избыточность. Для небольшого проекта содержимое JSON-файла спецификации может быстро разрастись до нескольких тысяч строк. В таком виде поддерживать этот файл вручную невозможно. Это — серьёзная угроза для самой идеи поддержания актуальной спецификации по мере развития API.


Не обязательно держать все в одном большом JSON-файле, можно же разбить как например здесь: github.com/Rebilly/RebillyAPI/tree/master/spec
+ использование YAML вместо JSON улучшает «сапортабилити» в разы.
К сожалению, вышедшая год назад OpenAPI 3.0 всё ещё мало поддерживается и мне не удалось найти достойных примеров документации на её основе

Поначалу да, но сейчас в Swagger UI уже таки поддерживается большинство возможностей OpenAPI 3.0.
Да, они так заявляют, но найти хороший пример мне не удалось. Поделитесь, если знаете.
Стандартный petstore вполне неплох. Из основного функционала OpenAPI 3.0 в Swagger UI не поддерживаются домены, это да. С другими ограничениями пока не сталкивался.
UFO just landed and posted this here
Sign up to leave a comment.

Articles