При разработке HTTP-сервисов в 1С часто возникают вопросы по организации безопасного и надежного кода. Рассмотрим детальный анализ типичного обработчика и разберем, какие архитектурные и технические решения помогут сделать ваш сервис профессиональным.
Исходный код, представленный в вопросе, содержит ряд критических уязвимостей и архитектурных недочетов:
ОписаниеОшибки() в ответе может раскрыть внутреннюю структуру данных, а коды ответов (400) не всегда соответствуют ситуации (например, отсутствие токена — это 403 Forbidden).Основное правило — не пишите всю бизнес-логику непосредственно в модуле HTTP-сервиса. Модуль должен заниматься только приемом запроса и формированием ответа. Всю работу с объектами 1С выносите в общие модули.
Разделим код на транспортный слой и слой бизнес-логики. Это позволит вам тестировать создание документов отдельно от HTTP-сервиса.
Рассмотрим структуру идеального обработчика:
Функция paymentsPOST(Запрос)
// 1. Проверка заголовков
Токен = Запрос.Заголовки.Получить("Token");
Если Токен = Неопределено Тогда
Возврат Новый HTTPСервисОтвет(403);
КонецЕсли;
// 2. Попытка парсинга JSON
Попытка
РезультатHTTPЗапроса = Запрос.ПолучитьТелоКакСтроку();
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(РезультатHTTPЗапроса);
ДанныеЗапроса = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Исключение
Возврат Новый HTTPСервисОтвет(400); // Некорректный JSON
КонецПопытки;
// 3. Вызов бизнес-логики (вынесено в общий модуль)
РезультатСоздания = ПлатежиСервер.СоздатьПлатеж(ДанныеЗапроса, Токен);
Если РезультатСоздания.Успех Тогда
Возврат Новый HTTPСервисОтвет(201);
Иначе
// Возвращаем код 500 или 422 в зависимости от типа ошибки
Ответ = Новый HTTPСервисОтвет(500);
Ответ.УстановитьТелоИзСтроки(РезультатСоздания.Ошибка);
Возврат Ответ;
КонецЕсли;
КонецФункции
Для предотвращения дублирования документов используйте «ключ идемпотентности». Попросите клиентов передавать уникальный идентификатор запроса (например, GUID) в заголовке Idempotency-Key.
Перед созданием нового документа в 1С всегда проверяйте наличие документа с таким ключом в регистре сведений или реквизите документа:
// Внутри бизнес-логики:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка ИЗ Документ.Платеж ГДЕ КлючИдемпотентности = &Ключ";
Запрос.УстановитьПараметр("Ключ", ВходящийКлюч);
Если НЕ Запрос.Выполнить().Пустой() Тогда
Возврат РезультатПовторногоЗапроса; // Возвращаем статус успешного выполнения
КонецЕсли;
Если процесс проведения документов занимает много времени, не проводите их онлайн. Рассмотрите следующие стратегии:
ЗаписьЖурналаРегистрации), чтобы иметь возможность отследить, какой именно запрос вызвал сбой.Следуя этим рекомендациям, вы превратите простой обработчик в надежный и масштабируемый сервис, готовый к реальной нагрузке в промышленной эксплуатации.