Function import - Операция выполняемая на стороне бэкенд системы. Это некоторая альтернатива обычным CRUD сервисам для случаев не подходящих под GET, POST, PUT, DELETE запросы. Может быть вызвана GET и POST методами. Например, проверки, запуски каких либо операций и прочее.
Пример создания
Для сервиса созданного в прошлой части создадим Function import по проверке наличия записи в таблице. (Максимально примитивная функция, в реальных задачах будете вызывать что-то реально стоящее))
Новая функция будет получать на вход ключ записи в таблице
SPFLI и возвращать информацию о ее наличии\отсутствии.
Первым делом следует создать выходную сущность:


В прошлый раз мы создавали сущность на основе данных из ABAP словаря. В этот раз для разнообразия создадим свойства вручную.

Создание функции

Первая функция будет использовать метод GET и возвращать только одну запись

Далее указываем входные параметры функции (Function Import Parameters). Точно таким же способом как и для сущности.
Выходные параметры имеют три варианта:
Без выходных параметров - тут, думаю, все ясно.
Entity type - можно использовать обычные entity или EntitySet в зависимости от кардинальности.
Complex Type - Это отдельная сущность, пример с которой будет рассмотрен ниже.

Сохраняем и перегенерируем сервис. Не забываем делать данную операцию при любых изменениях сервиса. Также необходимо обновить метаданные и сбросить кэш у сервиса.

Для обработки вызова необходимо переопределить метод EXECUTE~ACTION класса DPC_EXT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
METHOD /iwbep/if_mgw_appl_srv_runtime~execute_action. "Обратите внимание откуда можно взять выходной тип DATA ls_data TYPE zcl_zz_test_service_mpc=>ts_entityfcheck. CASE iv_action_name. WHEN 'runFunctionCheck' . DATA(lv_carrid) = it_parameter[ name = 'Carrid' ]-value. DATA(lv_connid) = it_parameter[ name = 'Connid' ]-value. ls_data-carrid = lv_carrid. ls_data-connid = lv_connid. SELECT SINGLE * FROM spfli INTO @DATA(ls_spfli) WHERE connid = @lv_connid AND carrid = @lv_carrid. IF sy-subrc = 0. ls_data-status = abap_true. ENDIF. copy_data_to_ref( EXPORTING is_data = ls_data CHANGING cr_data = er_data ). WHEN OTHERS. ENDCASE. ENDMETHOD |
Тест осуществляется в транзакции /IWFND/GW_CLIENT
Строка для запуска sap/opu/odata/sap/ZZ_TEST_SERVICE_SRV/runFunctionCheckPost?Connid='0017'&Carrid='AA'
Результат:

Далее сделаем POST функцию для того же самого действия. Собственно ничем не будет отличаться, кроме метода вызова.

В коде укажем, что новая функция должна идти по той же ветке, что и прошлая(Напоминаю, это чтобы сильно не мудрить с кучей кода)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
METHOD /iwbep/if_mgw_appl_srv_runtime~execute_action. "Обратите внимание откуда можно взять выходной тип DATA ls_data TYPE zcl_zz_test_service_mpc=>ts_entityfcheck. CASE iv_action_name. WHEN 'runFunctionCheck' OR 'runFunctionCheckPost'. DATA(lv_carrid) = it_parameter[ name = 'Carrid' ]-value. DATA(lv_connid) = it_parameter[ name = 'Connid' ]-value. ls_data-carrid = lv_carrid. ls_data-connid = lv_connid. SELECT SINGLE * FROM spfli INTO @DATA(ls_spfli) WHERE connid = @lv_connid AND carrid = @lv_carrid. IF sy-subrc = 0. ls_data-status = abap_true. ENDIF. copy_data_to_ref( EXPORTING is_data = ls_data CHANGING cr_data = er_data ). WHEN OTHERS. ENDCASE. ENDMETHOD. |
Параметры при запуске передаем точно так же.
sap/opu/odata/sap/ZZ_TEST_SERVICE_SRV/runFunctionCheckPost?Connid='0017'&Carrid='AA'

Третий ФМ будет немного отличаться. На вход подаем поле Carrid а на выходе хотим получить список значений из таблицы с этим полем. При При этом нам надо задать кардинальность 0..n или 1..n. И, что казалось бы логичным установить выходные параметры как EntitySet.
Что-то вроде этого:

Однако, при попытке вызова ФМ получим 405 ошибку: The specified HTTP method is not allowed for the resource identified by the Data Service Request URI
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="UTF-8"?> -<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <code>005056A509B11ED199D8826D151FC0FE</code> <message xml:lang="ru">The specified HTTP method is not allowed for the resource identified by the Data Service Request URI</message> -<innererror xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <transactionid>436D52A3C6FF0100E00624BBEE2DDE75</transactionid> <timestamp>20220422103601.6907860</timestamp> -<Error_Resolution> <SAP_Transaction>Run transaction /IWFND/ERROR_LOG on SAP Gateway hub system and search for entries with the timestamp above for more details</SAP_Transaction> <SAP_Note>See SAP Note 1797736 for error analysis (https://service.sap.com/sap/support/notes/1797736)</SAP_Note> </Error_Resolution> </innererror> </error> |
Это можно обойти указав тип выходного параметра как Complex Type
Создание Complex Type:


Добавляем выходные поля. Хватит и двух для примера.

Указываем этот тип в настройке новой функции:

Реализуем ветку для сбора данных в методе EXECUTE_ACTION
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
METHOD /iwbep/if_mgw_appl_srv_runtime~execute_action. "Обратите внимание откуда можно взять выходной тип DATA ls_data TYPE zcl_zz_test_service_mpc=>ts_entityfcheck. CASE iv_action_name. WHEN 'runFunctionCheck' OR 'runFunctionCheckPost'. DATA(lv_carrid) = it_parameter[ name = 'Carrid' ]-value. DATA(lv_connid) = it_parameter[ name = 'Connid' ]-value. ls_data-carrid = lv_carrid. ls_data-connid = lv_connid. SELECT SINGLE * FROM spfli INTO @DATA(ls_spfli) WHERE connid = @lv_connid AND carrid = @lv_carrid. IF sy-subrc = 0. ls_data-status = abap_true. ENDIF. copy_data_to_ref( EXPORTING is_data = ls_data CHANGING cr_data = er_data ). WHEN 'runFunctionCheckPostMany'. DATA lt_data_many TYPE TABLE OF zcl_zz_test_service_mpc=>typeexitmany. DATA(lv_carrid_m) = it_parameter[ name = 'Carrid' ]-value. SELECT * FROM spfli INTO CORRESPONDING FIELDS OF TABLE @lt_data_many WHERE carrid = @lv_carrid_m. copy_data_to_ref( EXPORTING is_data = lt_data_many CHANGING cr_data = er_data ). WHEN OTHERS. ENDCASE. ENDMETHOD. |
