Мой коллега Денис рассказывает о практическом способе интеграции HTTP-сервисов 1С со Swagger через расширение swagger-1С, позволяющим автоматически генерировать живую интерактивную документацию API без ручного описания JSON-схем.
Введение. Зачем это вообще нужно (и почему все статьи — не про то)
Реальная ситуация из прошлого. В чат с интегратором падает сообщение: «А какой формат даты вы принимаете? Структура JSON есть? Можно пример?» И вы в десятый раз скриншотите свою тестовую обработку или скидываете ссылку на устаревший Word-файлик, который уже никто не обновлял.
В этот момент хочется одного, чтобы внешний мир просто понимал ваше API без ежеминутных уточнений. Чтобы разработчик на другой стороне открыл браузер и увидел: вот методы, вот параметры, вот примеры ответов. И чтобы эта документация всегда соответствовала реальности, потому что она является частью кода.
В мире за пределами 1С такая проблема решена давно и элегантно. Там есть Swagger (он же OpenAPI) — стандарт описания REST API, который понимают все: от фронтендеров до тестировщиков и генераторов клиентского кода.
В 1С же с этим — беда. Из коробки — ничего. Типовые статьи в интернете либо предлагают с нуля писать JSON-схемы руками (спойлер: никто не будет), либо ограничиваются абстрактными «создайте HTTP-сервис и опишите его в комментариях», умалчивая о граблях, на которых вы гарантированно споткнетесь.
А грабли эти увесистые. Например, тот самый CORS, который заставит вас проклясть тот день, когда вы решили подружить браузер с 1С. Или SetHandler 1С-application, молча сбрасывающий ваши заголовки. Или несоответствие типов, когда Swagger показывает одно, а 1С ждет совсем другое.
В этой статье будет инструкция для тех, кто устал читать консоли запросов вслух заказчику. Мы разберем:
-
один из лучших подходов к внедрению Swagger в 1С;
-
примеры с кодом и комментариями, пройдем по живому примеру HTTP-сервиса;
-
и покажу некоторые «грабли», с которыми я столкнулся.
Поехали.
Раздел 1: что такое Swagger/OpenAPI и зачем он 1С-нику.
1.1. Немного теории
Swagger — это целая экосистема инструментов, в центре которой лежит спецификация OpenAPI Specification (OAS).
OpenAPI — это, если можно так сказать, технический паспорт, где на понятном (и человеку, и машине) языке описано:
-
какие URL (методы) у нашего HTTP сервиса;
-
какие параметры можно передать (и где — в заголовке, в строке запроса или в теле);
-
какой формат данных (JSON, XML) он понимает;
-
что он вернет в случае успеха, а что — при ошибке.
Этот «паспорт» можно написать вручную в формате JSON или YAML, а можно сгенерировать автоматически из кода. И вот здесь начинается магия.
На основе этого JSON-файла другие инструменты (например, Swagger UI) строят интерактивную веб-страницу.
Необходимо учесть, что наш Swagger поддерживает несколько интерфейсов (ReDoc, Scalar, Stoplight и RapiDoc). Об этом можно прочитать здесь.
Важно: столкнулся с проблемой при отображении сервиса в браузере, а именно непонятными ошибками, из-за которых описание в браузере вообще не генерировалось. Выход (в моем случае) в адресной строке указал интерфейс RapiDoc (http://<Адрес_опубликованной_базы>/hs/swagger/index.html?ui=RapiDoc ), и все «взлетело».
Мы для примеров будем использовать RapiDoc, и наша веб-страница будет выглядеть примерно так:

На этой странице любой желающий может:
-
Увидеть полный список доступных методов API (на левой панели).
-
Прочитать, что каждый метод делает, какие параметры принимает и что отдает.
-
Тут же, в браузере, отправить тестовый запрос и увидеть реальный ответ от сервера.
Просто открыл браузер и работаешь.
1.2. Три железобетонных аргумента для внедрения.
-
Стандартизация API. Все ваши методы и структуры данных описаны в едином, общепринятом формате. Интегратору не нужно вникать в «фирменный» стиль 1С. Он просто читает документацию так же, как читает ее для любого современного REST API.
-
Автодокументирование и «единство кода и правды». Это ключевой момент. Если вы правильно организуете процесс, Swagger-спецификация будет генерироваться автоматически на основе вашего кода. Вы меняете логику — документация обновляется сама при следующей сборке. Забудьте про «документацию в Word».
-
Упрощение тестирования и интеграции. Внешние системы и разработчики могут начать работать с вашим API немедленно, не отвлекая вас вопросами. Это экономит часы переписок и нервов с обеих сторон. Плюс вы сами можете использовать Swagger UI для быстрых тестов своей разработки.
1.3. Почему в 1С с этим сложно.
Платформа не умеет генерировать спецификацию по вашим HTTP-сервисам. Все, что мы будем делать дальше, — это описывать наши HTTP-сервисы, красиво и удобно.
Что потребуется от вас:
-
только установка расширений в конфигурацию;
-
иногда небольшие настройки веб-сервера (в случае каких-то трудностей).
И это нормально. Платформа 1С развивается в сторону веб-технологий, но пока что многие вещи приходится делать руками.
Раздел 2: один подход, который реально работает.
Swagger —1С – это расширение, которое ставится в конфигурацию, само подхватывает твои HTTP-сервисы через специальные общие модули-описатели и прямо в рантайме отдает и Swagger UI, и спецификацию.
Три причины использования:
-
Живая документация. Расширение само генерирует спецификацию на лету — не надо руками запускать скрипты при каждом чихе.
-
Минимум телодвижений. Установил расширение, включил галку публикации, создал модуль-описание по шаблону — всё работает.
-
Проверка параметров из коробки. Расширение умеет само проверять входящие данные на соответствие.
Единственный момент — придется немного подружить это хозяйство с веб-сервером.
Раздел 3: Установка и настройка расширения.
3.1. Где брать.
3.2. Установка.
Заходим в конфигуратор целевой базы.
Создаем новое расширение (имя любое, например Swagger).
Через меню «Конфигурация -> Загрузить конфигурацию из файла» и выбираем наш файл расширения. Обновляем конфигурацию базы.
3.3. Публикация на веб-сервере.
Тут важный момент, про который забывают в половине инструкций.
После установки расширения нужно переопубликовать базу на веб-сервере и обязательно поставить галку: «Публиковать HTTP сервисы расширений по умолчанию».
Без этой галки ваше расширение будет лежать мертвым грузом, и по адресу /hs/swagger/index.html будет 404.
После публикации перезапустить веб-сервер. IIS, Apache — не важно. Просто рестарт, чтобы подхватились все настройки.
3.4. Проверка, что всё ожило.
Открываем браузер и идем по адресу:
http://<Адрес_опубликованной_базы>/hs/swagger/index.html*
* — добавляется имя интерфейса, например: ?ui=RapiDoc
Если видим картинку примерно такой, как на рисунке, то у вас все заработало.

Раздел 4: описываем первый HTTP-сервис.
4.1. Что хочет расширение.
Расширение ищет описания HTTP-сервисов в общих модулях, имена которых строятся по шаблону:
«<Имя_HTTP_сервиса>Описание».
То есть если ваш HTTP-сервис называется ОбменДанными, то общий модуль-описание должен называться ОбменДаннымиОписание. Регистр важен.
4.2. Живой пример: сервис остатков.
Для примера возьмем типовую задачу — HTTP-сервис, который отдает остатки по складу.
Имя HTTP-сервиса в метаданных: ОстаткиСклада.
Шаблон URL: /stocks.
Метод: GET.
Параметры запроса: storageCode (код склада, обязательный), productFilter (фильтр по товарам — массив ID, опционально).
Ответ: массив объектов с полями productId, quantity, price.
4.3. Создаем модуль-описание.
Создаем общий модуль с именем ОстаткиСкладаОписание.
В этом модуле нам нужно описать все методы нашего HTTP-сервиса. Три обязательные функции:

Вот как будет выглядеть описание для нашего GET-метода в функции ПолучитьОписаниеHTTPСервиса():
// Возвращает основной массив описаний HTTP-Сервиса// // Возвращаемое значение:// Массив - Список сформированного описания методов HTTP-сервиса. См. https://zerobig.github.io/swagger-1c/docs/getting-started/methods_func_style //Функция ПолучитьОписаниеHTTPСервиса() ЭкспортМетоды = Swag_Описание.Метод("ОстаткиСкладаGET").ОписаниеМетода("Остатки товаров на складах").ДетальноеОписаниеМетода(НСтр("ru = 'Получение данных по остаткам на складах.'")) .ПараметрURL("storageCode").ОписаниеПараметра("Код склада, например ""0897""").Тело().ТипТела("application/json").СхемаТела("ОстаткиСкладаGET").Ответ(200).ОписаниеОтвета("Success").ТипОтвета("application/json").СхемаОтвета("ОстаткиСклада_Ответ").Сформировать();Возврат Методы;КонецФункции
А вот так в функции ПолучитьОбъектыHTTPСервиса():
// Возвращает массив объектов описания HTTP-Сервиса// // Возвращаемое значение:// Массив - Список сформированных объектов описания. См. https://zerobig.github.io/swagger-1c/docs/getting-started/objects_func_style//Функция ПолучитьОбъектыHTTPСервиса() ЭкспортОбъекты = Новый Массив;Объекты = Swag_Описание.Объект("ОстаткиСкладаGET") // Описание объекта.Свойство("productFilter").ОписаниеСвойства("Код номенклатуры через запятую").ТипЗначения("array").Схема("ТоварыОтбор") .Объект("ТоварыОтбор").Свойство("id").ОписаниеСвойства("Код номенклатуры").ТипЗначения("string").Пример("0098778,0098777,0066778,0098668").Объект("ОстаткиСклада_Ответ") .Свойство("id").ОписаниеСвойства("Код номенлатуры").ТипЗначения("string").Пример("202140") .Свойство("name").ОписаниеСвойства("Наименование номенлатуры").ТипЗначения("string").Пример("Мыло детское 100гр") .Свойство("quantity").ОписаниеСвойства("Количество").ТипЗначения("integer").Пример(456) .Свойство("price").ОписаниеСвойства("Цена").ТипЗначения("string").Пример("541,5") .Сформировать();ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Объекты, Swag_ОбщиеОписанияПереопределяемый.ОбъектErrors422());ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Объекты, Swag_ОбщиеОписанияПереопределяемый.ОбъектErrors404());Возврат Объекты;КонецФункции
4.4. А где же сам код?
Важный момент: модуль-описание не содержит исполняемого кода. В нем живут только описания сервиса. Сам обработчик как был в модуле HTTP-сервиса, там и остается. Расширение просто читает наши функции и превращает их в спецификацию.
Но если мы хотим использовать встроенную проверку параметров (а мы хотим), то в коде обработчика надо добавить вызов метода ПроверитьПараметры из расширения.

В модуле HTTP-сервиса ОстаткиСклада обработчик будет выглядеть примерно так:
функция stocksGET (Запрос)// Проверяем входящие параметры по описанию из модуля ОстаткиСкладаОписаниеРезультатПроверки = Swag_ОбработкаНТТР.ПроверитьПараметры("ОстаткиСклада", // Имя НТТР-сервиса"GET", // Имя метода (должно совпадать с описанием)Запрос // Сам запрос);Если Не ПустаяСтрока(РезультатПроверки) ТогдаВозврат Swag_ОбработкаНТТР.ПолучитьОтветОшибки(РезультатПроверки, Истина);КонецЕсли;// --- здесь основная логика получения остатков ---МассивОстатков = МодульОбработкиНТТРСервисов.ПолучитьОстатки(Запрос.Параметры["storageCode"]);Ответ = Новый НТТРСервисОтвет(200);Ответ.УстановитьТелоИзСтроки(МассивОстатков);// Проверяем ответ на соответствие описаниюВозврат Swag_ОбработкаНТТР.ПроверитьОтвет("ОстаткиСклада","GET",Ответ);КонецФункции
Этот код делает две вещи:
-
До выполнения логики проверяет, все ли обязательные параметры пришли и правильного ли они типа.
-
После формирования ответа проверяет, соответствует ли структура данных тому, что мы обещали в описании.
Если что-то не так, расширение само вернет человекочитаемую ошибку. Красота.
Раздел 5: проверка результата.
После того, как модуль-описание создан и код обработчика дописан:
-
Обновляем конфигурацию базы.
-
Открываем браузер по адресу http://<сервер>/<база>/hs/swagger/index.html.
-
Если всё сделано правильно, видим наш метод GET /stocks с полным описанием параметров и структур ответов.

4. Тыкаем Try, вводим код склада, жмем Execute и получаем реальный ответ от сервера прямо в браузере.
Некоторое описание на скриншотах для примера:

Заключение
Мы прошли путь от полного отсутствия документации до работающего Swagger UI, который:
-
автоматически генерируется;
-
проверяет входящие параметры и ответы;
-
позволяет интеграторам самим тестировать методы без нашего участия;
-
не требует танцев с бубном при каждом изменении API.
Пришлось:
-
поставить расширение;
-
создать модули-описания для каждого HTTP-сервиса;
-
приучить себя писать код описания сервисов определенным образом.
Но, поверьте моему опыту, когда в следующий раз интегратор вместо «а скиньте пример» просто откроет Swagger и сам всё увидит, вы скажете себе спасибо.
P.S. Весь код описания сервисов написан исключительно на тестовой базе для тестирования. Все исходники расширения и примеры кода из статьи можно найти в репозитории zerobig/swagger-1c на GitHub.
ссылка на оригинал статьи https://habr.com/ru/articles/1024666/