Имя: Пароль:
1C
1С v8
Вопрос к знатокам HTTP сервисов
0 andryscha1c
 
26.08.21
10:27
Есть произвольный http сервис и реализован следующий обработчик для регистрации платежей // плательщиком
Опишите что бы вы изменили в коде ниже? Корректно ли все?

Функция paymentsPOST(Запрос) // Запрос - HTTPЗапрос
    Токен = Запрос.Заголовки.Получить("Token");
    Если Токен = Неопределено Тогда
        Возврат Новый HTTPСервисОтвет(400);    
    КонецЕсли;    
    Плательщик = Справочники.Плательщики.НайтиПоРеквизиту("Токен", Токен);
    Если Плательщик.Пустая() Тогда
        Возврат Новый HTTPСервисОтвет(403);    
    КонецЕсли;    
    ЧтениеJSONДанных = Новый ЧтениеJSON;
    РезультатHTTPЗапроса = Запрос.ПолучитьТелоКакСтроку();
    ЧтениеJSONДанных.УстановитьСтроку(РезультатHTTPЗапроса); //Запрос.ПолучитьТелоКакСтроку());
    Структура = ПрочитатьJSON(ЧтениеJSONДанных);
    ЧтениеJSONДанных.Закрыть();     
    Если Структура.Свойство("amount")  = Неопределено Тогда
        Возврат Новый HTTPСервисОтвет(400);    
    КонецЕсли;    
    Попытка
        НовыйПлатеж = Документы.Платеж.СоздатьДокумент();
        НовыйПлатеж.Дата        = ТекущаяДата();
        НовыйПлатеж.Плательщик    = Плательщик;
        НовыйПлатеж.Сумма        = Структура.amount;
        // ...
        НовыйПлатеж.Записать(РежимЗаписиДокумента.Проведение);
    Исключение
        НовыйПлатеж.Записать(РежимЗаписиДокумента.Запись);
        Ответ = Новый HTTPСервисОтвет(400);
        Ответ.УстановитьТелоИзСтроки(ОписаниеОшибки(),КодировкаТекста.UTF8);
        Возврат Ответ;
    КонецПопытки;
    Возврат Новый HTTPСервисОтвет(201);
КонецФункции
1 ДенисЧ
 
26.08.21
10:29
Ответ = Новый HTTPСервисОтвет(400);
Ответ.УстановитьТелоИзСтроки(ОписаниеОшибки(),КодировкаТекста.UTF8);

Тут не по феншую. Надо понимать, почему ошибка. И возвращать правильный код. От 403, 404 до 500.
2 Ёпрст
 
26.08.21
10:30
(0)

вот это за гранью добра


Попытка
        НовыйПлатеж = Документы.Платеж.СоздатьДокумент();
        НовыйПлатеж.Дата        = ТекущаяДата();
        НовыйПлатеж.Плательщик    = Плательщик;
        НовыйПлатеж.Сумма        = Структура.amount;
        // ...
        НовыйПлатеж.Записать(РежимЗаписиДокумента.Проведение);
    Исключение
3 Ёпрст
 
26.08.21
10:30
запустил значится это изделие N-раз, слепили N-документов
4 Ёпрст
 
26.08.21
10:31
В ответе, может быть и не json, и
Структура = ПрочитатьJSON(ЧтениеJSONДанных); эта шляпа может в исключение вылететь
5 Галахад
 
гуру
26.08.21
10:38
Разделить логику передачи данных и работы с объектами.
6 maxx079
 
26.08.21
10:39
(0) Коды ошибок надо согласовать с разработчиками этого hhtp-сервиса - возвращать те коды, что они могут и будут обрабатывать.
Добавить описание ошибки, опять же при условии, будут ли они эти ошибки анализировать
Как уже упомянули - добавить проверку, что нужный документ уже был загружен ранее. В этом случае либо ничего не менять, либо сделать перезаполнение существующего документа, а не создавать новый.

(4) Проверку на json делать не обязательно. Если запрос сюда пробился, значит, он уже соответствует API.
А вот завернуть весь обработчик в Попытку-Исключение следует. Чтобы в случае любой нештатной ситуации вернуть ошибку.
7 Garykom
 
гуру
26.08.21
10:46
(0) переписать нафуй нормально
лапшекод же, неужели сам не видишь

получение данных, обработка данных и отправка/возврат должны быть отделены
8 PROGRAM1S
 
26.08.21
10:57
(0)
1. Если Токен = Неопределено Тогда
        Возврат Новый HTTPСервисОтвет(400);    
    КонецЕсли;

Добавь в тело запроса ошибку, что нет токена в заголовках

2. чтение JSON оберни в попытку с возвратом ошибки 400 в случае исключения

3. Если ошибка возникла при проведении документа, то возвращай ошибку 500

4. Если запрос выполнился, то в теле запроса верни идентификатор созданного документа

5. лучше в модуле сервиса оставить только код по обработке запроса и формированию ответа, а код по созданию документа вынести в общий модуль или в модуль менеджера/объекта.
9 acht
 
26.08.21
10:58
(6) > Если запрос сюда пробился, значит, он уже соответствует API.
С фига-ли? Это тебе не SOAP, где схема проверяется.
10 acht
 
26.08.21
10:58
(8) Первый случай, это вообще 403 в чистом виде
11 PROGRAM1S
 
26.08.21
11:00
(10) можно и 403, но в теле ответа написать, что нет заголовка "Token". Может сам токен есть, просто не туда засунули
12 fisher
 
26.08.21
11:03
(8) +1
13 Garykom
 
гуру
26.08.21
11:06
(8) >3. Если ошибка возникла при проведении документа, то возвращай ошибку 500

проводить онлайн в обработке запроса идеологически неправильно
правильно ставить в очередь и возвращать id задания, затем в фоне проводить и отдельный метод получения статуса задания-проведения
14 Garykom
 
гуру
26.08.21
11:08
(13)+ как id задания логично использовать уид
15 acht
 
26.08.21
11:10
(13) Только в случае тяжелого проведения. Иначе схлопочешь ситуацию, что затраты на два обращения и побочную запись/чтение в регистр превысят затраты на одно обращение.
16 Garykom
 
гуру
26.08.21
11:18
(15) лучше сразу продумать и сделать правильно
иначе потом будет очень сложно отделить сервис и сделать чтобы в моменты регламентных операций (обновление конфы и прочее) сервис был доступен 24/7
17 Галахад
 
гуру
26.08.21
11:22
(16) Хм. А как сделать сервис доступным во время "(обновление конфы и прочее)"?
18 ДенисЧ
 
26.08.21
11:24
(17) Через прослойку. В виде отдельной 1с-базы. Которая тоже будет обновляться и прочее.
А чтобы от её обновлений защититься - сделать ещё одну.
19 Галахад
 
гуру
26.08.21
11:26
(18) Ну про микросервис я догадывался. Но все же?
20 acht
 
26.08.21
11:28
(19) Две базы и балансер. Обслуживание асинхронное.

Ну ладно, балансер на го, работающий на ардуине.
21 Garykom
 
гуру
26.08.21
11:31
(20) про nginx не слыхал?
22 Галахад
 
гуру
26.08.21
11:33
(20) (21) Хм. Примерно так и думал. :-)
23 Garykom
 
гуру
26.08.21
11:43
(22) вторая база может быть как РИБ копией, так и "микросервисом" накопительным
24 BeerHelpsMeWin
 
26.08.21
11:49
(16) Если база недоступна в моменты регламентных операций - то это проблемы того, кто к ней обращается.
25 Garykom
 
гуру
26.08.21
11:51
(24) Если невозможно обеспечить доступность 24/7 следует с http/веб-сервисов переходить на очереди/брокеры сообщений
26 BeerHelpsMeWin
 
26.08.21
11:59
(25) И если недоступен брокер сообщений, то это все равно проблемы того, кто к нему обращается.
27 acht
 
26.08.21
12:03
28 Дык ё
 
26.08.21
13:32
(0) Если Структура.Свойство("amount")  = Неопределено Тогда

так не бывает
29 fisher
 
26.08.21
13:44
(16) > лучше сразу продумать и сделать правильно
Главное, чтобы это "правильно" не было оверинженирингом.
Асинхронность добавляет сложности и добавляет неудобств. Поэтому сразу пихать ее во все дыры на случай когда через сто лет это окупится, если компания в 200 раз вырастет - такое себе.
30 fisher
 
26.08.21
13:53
На практике удобно и чаще всего достаточно делать на синхронных, но быстрых операциях. По возможности без блокировок. Тяжелые проведения ессно не очень разумно выполнять синхронно. Но и это может быть допустимо. От ситуации зависит. В качестве компромисса иногда допустимо синхронно писать, а проводить уже очередью.