Привет! Меня зовут Александр Панфилов, я фронтенд-разработчик и тимлид с 9-летним опытом. В этой статье я хочу поделиться своим опытом глубокой работы со Swagger — инструментом, который кажется простым только на первый взгляд. На практике же его тонкости могут отнять немало времени, и сегодня я разберу именно те моменты, которые потребовали от меня наибольших усилий.
В своей работе столкнулся с тем, что Swagger игнорирует мой заголовок authorization; не знал, как описать два разных типа запросов к одному эндпоинту и т. д. Далее по тексту я опишу, как мне удалось обойти такие проблемы.
Что такое Swagger и OpenAPI?
Swaggerи OpenAPI — это, по сути, синонимы для разработчика. Речь идет о наборе спецификаций, которые описывают структуру запросов и ответов для каждого эндпоинта API
Почему я решил погрузиться в эту тему?
В рамках рабочего проекта мне пришлось временно выполнять роль аналитика, что подразумевало активную работу со спецификацией эндпоинтов.
- Общаясь с Java-разработчиками, я открыл для себя подход API-first:
Смежные команды заключают контракт по эндпоинтам. - Контракт детально описывается и согласовывается. Утвержденная спецификация используется для генерации кода как на бэкенде, так и на фронтенде.
- Автоматическая кодогенерация — ключевой фактор. Нам удалось настроить этот процесс, что значительно ускорило разработку.
Работа с параметрами: нестандартный пример с enum
В моем личном проекте есть два модуля — блоги чат, каждый со своей формой авторизации. Чтобы не дублировать эндпоинты, я использовал единую точку входа, а для выбора логики авторизации — enum. В зависимости от переданного значения активируется соответствующая логика.
Раньше я плотно не работал с настройкой Swagger и был удивлен, что редактировать поля можно только после нажатия кнопки «Try it out».
Структура параметра с enum:
- name — имя параметра;
- enumName — произвольное имя enum;
- enum — допустимые значения;
- description — описание;
- examples — примеры значений. Это объект, где каждый ключ содержит:
- value — конкретное значение;
- description — пояснение, зачем оно нужно.
Использование examples особенно удобно: это дает полное представление о возможных значениях параметра.
Несколько типов тел запроса для одного эндпоинта
Иногда один эндпоинт должен обрабатывать разные форматы данных. В Swagger это реализуется через механизм examples.
В решении этого вопроса мне также помог examples.
- description — пояснение, для чего предназначено это тело.
- schema — JSON-схема тела запроса. Она здесь используется намеренно для добавления возможности выбора между используемыми вариантами ответа;
anyOf — оператор, позволяющий выбрать одну из нескольких схем. Как вариант, можно еще использовать oneOf — будет тот же смысл, но я посчитал, что здесь лучше использовать anyOf.
$ref и getSchemaPath — ссылки на DTO-схемы (в моем случае — на основе class-validator). - examples — примеры для каждой схемы.
Важно! Если указать несколько схем в schema, но не заполнить examples, интерфейс Swagger не предоставит выбора.
Заголовки и авторизация
Моя авторизация построена на токенах, передаваемых в заголовках. Однако при добавлении заголовка authorizationв Swagger он не отправлялся в запросе. Оказалось, что в nestjs/swagger этот заголовок по умолчанию игнорируется.
На картинке приведен заголовок. Когда нажимал «try it», то запрос уходил, но заголовка в нем не было.
Решение: Я добавил несколько способов авторизации — через accessToken и refreshToken.
Чтобы использовать кастомный заголовок, нужно:
- Нажать на значок замка;
- Ввести актуальный токен;
- Важный момент: Swagger запоминает значение и автоматически подставляет его во все запросы с этой авторизацией.
Со временем я решил скрыть стандартный заголовок authorization, чтобы не вводить в заблуждение.
Чего лично мне не хватает в работе со swagger в nest.js?
Главный недостаток — отсутствие встроенной генерации кода по OpenAPI-спецификации, как это реализовано в Java. В остальном инструмент полностью отвечает моим запросам.
Выводы
- Swagger — мощный инструмент, но его тонкости требуют времени на освоение.
- Использование examples и anyOf значительно расширяет возможности документации.
- Работа с заголовками в Nest.js имеет свои нюансы, но они решаемы.
- ИИ может ускорить работу, но лично я предпочитаю писать код вручную — так надежнее.
Надеюсь, мой опыт поможет вам сэкономить время. Спасибо за внимание, до встречи в следующих статьях
Удачи в освоении Swagger)