Когда нужно сделать несколько запросов к 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)


  1. I00I
    25.12.2017 15:39
    +1

    Вдруг кому пригодится stoplight.io — для описания/тестов/моков апи. Всё в одном месте


  1. Mingun
    25.12.2017 19:39
    +1

    Гм. На ваше описание ругается онлайн-редактор Swagger (как старый, так и новый): в строке 5424 написано:


              type: byte

    Но спецификация Swagger для целых чисел поддерживает только тип integer с необязательным форматом int32 или int64. Может быть, имелось в виду (судя по описанию):


              type: string
              format: byte

    или даже


              type: string
              format: octet

    ?
    Ну и многие модели объявлены, но фактически не используются в спецификации (новый редактор не показывает предупреждения, лучше смотреть в старом).


    1. eyeofhell Автор
      25.12.2017 19:54

      Автогенератор ошибся. Респект, благодарности, поправим!


  1. Spoofi
    26.12.2017 09:49

    Для .NET проектов с WebAPI есть еще замечательный пакет — Swashbuckle. Генерирует все автоматически и имеет замечательный web-интерфейс.
    Пользуемся уже очень давно и все нарадоваться не можем :)