OpenAPI(swagger): Опыт использования
Нам потребовалось согласовать с заказчиком и реализовать более дюжины API. Каждое всего из нескольких вызовов, но общий объем заставлял задуматься о стандартизации этого процесса.
Мы попробовали использовать swagger (он же OpenAPI ). Впечатления получились неоднозначные.
1
Нам необходимо было использовать swagger в направлении от документации к коду. Возможно, в обратном направлении swagger и хорош (по готовому коду создать описание), но генерировать из swagger-описания код на java у нас не получилось.
Перебрали все имеющиеся в swagger codegen варианты, и поняли, что проще написать руками, чем чистить то, что генерирует codegen.
2
Поддержка XML в swagger очень условная. По крайней мере, когда мы попробовали сгенерировать по swagger-описанию клиента python, чтобы написать тесты, мы обнаружили, что в этом клиенте вообще нет работы с XML.
Мы на скорую руку добавили работу с XML, но не в таком состоянии, чтобы закинуть это патчем в swagger codegen. Так что теперь у нас локально патченный код и нельзя просто брать свежие codegen.
Кроме того, есть странные особенности в генерации примеров из swagger ui, если формат - XML. В частности, имена тегов не берутся из xml: name, надо еще чтобы был такой же title, который, казалось бы, должен отвечать только за имя объекта. Поэтому, когда речь о параметрах запроса, где не определить title, приходится выносить описание в отдельный объект, только чтобы точно определить имя тега.
3
Сервер для Python генерится на tornado + connexion.
Казалось бы, все ок.
Но обнаружилось, что торнадо при этом невозможно использовать в асинхронном режиме. Что как бы очень печально для эмулятора. Эмулируем, например, паузу - и привет, все соединения ждут эту паузу.
Задал вопрос в connexion, и получил изумительный ответ:
we would need to actually do quite some changes in other parts of the Connexion code to support Tornado async. For now the answer is “not possible”. :/
И дело не только в режиме использования tornado.
Допустим, нам надо во время обработки вызова сервера эмулятора сделать асинхронно другой вызов, через сгенерированный swagger codegen клиент.
На python в swagger генерится код клиента, который вроде поддерживает асинхронность. Смотрим внутрь него и видим, что в асинхронном режиме единственное что он делает - стартует еще одну нитку. Прекрасно, а если в нитке exception? Это никак не обрабатывается.
4
Жесткая формализация и верификация описания API это безусловно большое благо.
Не смотря на все описанные выше проблемы, используя swagger мы получили четкое описание API, многие ошибки в котором обнаруживаются на фазе проверки swagger-ом.
Его легко рефакторить.
Из него мы генерили код для эмуляторов и тестовых клиентов, что позволяло нам существенно экономить усилия на фазе активного изменения API. По сути, мы могли макетировать - а давайте попробуем вот сюда добавить вызов, перенести параметры из этого вызова в тот. И посмотрим, что получится, попробуем это использовать.
Swagger сам по себе мы с удовольствием заменили бы на что-то иное, но вот на что?