Когда нужно сделать несколько запросов к HTTP API, разработчик обычно берет свой привычный язык/фреймворк и быстро пишет аналог curl в коде: HTTP-запрос, минимальный контроль ошибок, query- или json-аргументы, парсинг json body с названиями полей в виде строк. Все это замечательно работает, пока проект не начинает расти и несколько вызовов не превращаются в несколько десятков, а куски низкоуровневого кода не начинают размножаться копипастой. А дальше — стандартный набор багов, рожденных копипастой, которые начинают понемногу есть время у разработчика.
Swagger/OpenAPI — один из «комбайнов» для работы с HTTP API. Это язык описания API (недавно произошло объединение проектов генератора и спеки), генераторы серверного и клиентского кода, документации, тестов — много всяких полезных штук. Под катом я покажу, как по «человеческому» описанию API на сайте компании в несколько строк кода составить OpenAPI-описание и сгенерировать клиент на Python. И чем такой клиент будет лучше, чем вручную написанный код.
Используем Voximplant HTTP API в качестве подопытного
Voximplant HTTP API cделан нами больше пяти лет назад и позволяет полностью управлять облаком: создавать сценарии работы со звонками, пользователей, арендовать и подключать номера, инициировать звонки и прочая, прочая, прочая. Админка для разработчика целиком сделана поверх API и является неплохой иллюстрацией к его использованию, если заглянуть в лог HTTP-запросов браузера.
Для примера возьмем endpoint /AddScenario, который загружает в облако JavaScript-код. Этот код будет выполняться при входящих/исходящих звонках и управлять этими звонками (соединять друг с другом, распознавать и синтезировать голос, записывать и так далее). В документации мы написали, что HTTP API можно использовать с любым verb (GET, POST и так далее), аргументы можно передавать url-encoded или body-encoded, а возвращаемое значение это JSON с документированными полями. Также большинство API используют единую схему аутентификации: в качестве идентификатора можно использовать id аккаунта, имя или email, а в качестве подтверждения api key, пароль или временную session id.
Описываем HTTP API с помощью Swagger
Несмотря на то, что официальный сайт встречает нас спецификацией версии 3.0, это обманка. Генератор пока может только 2.0, которую мы и будем использовать. Swagger поддерживает описание в формате YAML или JSON, и для уменьшения объема кода я буду использовать YAML. «Вводная» часть описания API фиксирует версию спеки и корневой URL, по которому будут делаться запросы:
Описываем Endpoint:
Описываем параметры авторизации. Если мы делаем описание для себя, то из возможных вариантов достаточно описать тот, который будем использовать. Например, по id аккаунта и api key:
Описываем имя и код сценария. Наш сервер одинаково обрабатывает параметры из url и body, но сетевая инфраструктура вряд ли обрадуется, если мы отправим запрос с десятком-другим килобайт текста в URL. Поэтому для scenario_script мы прописываем строго передачу через body:
Последний штрих — возвращаемые значения. Все API возвращают JSON:
Генерируем клиент с помощью swagger-codegen
С получившимся файлом-описанием API можно сделать много интересных штук: сгенерировать сервер, документацию, тесты. Мы сгенерируем клиент! К примеру, на Python — Swagger поддерживает десятки комбинаций языков программирования и фреймворков. Кодогенератор проще всего скачать как jar-архив и запустить с помощью предварительно установленной Java:
Результатом команды будет полностью готовый проект на Python с документацией в формате .md, настроенными тестами, деплоем и другими хорошими штуками. Который можно сразу же попробовать в работе:
Зачем генерировать клиент?
Сгенерированный клиент — это, прежде всего, контроль ошибок. Вы один раз описываете свой (или чужой) HTTP API со всеми ограничениями и объектами, после чего сгенерированный код проверят правильность вызовов и использования. Синтаксис OpenAPI позволяет задавать переиспользуемые фрагменты, так что повторяющиеся части не будут копипастой даже в спецификации.
Swagger умеет множество языков и фреймворков, так что один раз описав API, вы получите готовые клиенты для Python, Java, Ruby, PHP, Node.js, Android, iOS — список можно продолжать довольно долго:
Для нашего HTTP API мы генерируем Swagger-описание в формате JSON, если интересно попробовать, то оно доступно здесь.
Комментарии (4)
Mingun
25.12.2017 19:39+1Гм. На ваше описание ругается онлайн-редактор Swagger (как старый, так и новый): в строке 5424 написано:
type: byte
Но спецификация Swagger для целых чисел поддерживает только тип
integer
с необязательным форматомint32
илиint64
. Может быть, имелось в виду (судя по описанию):
type: string format: byte
или даже
type: string format: octet
?
Ну и многие модели объявлены, но фактически не используются в спецификации (новый редактор не показывает предупреждения, лучше смотреть в старом).
Spoofi
26.12.2017 09:49Для .NET проектов с WebAPI есть еще замечательный пакет — Swashbuckle. Генерирует все автоматически и имеет замечательный web-интерфейс.
Пользуемся уже очень давно и все нарадоваться не можем :)
I00I
Вдруг кому пригодится stoplight.io — для описания/тестов/моков апи. Всё в одном месте