oData(Open Data Protocol) - открытый веб-протокол для передачи данных. Общение по протоколу осуществляется по HTTP протоколу путем обмена json и xml.
В рамках SAP обычно мы говорим об обмене данных между фронтом и бэкендом, хотя применение гораздо шире.
Рассмотрим пример создания простого сервиса для работы с данными таблиц SPFLI и SFLIGHT:
Ведение сервисов осуществляется в транзакции SEGW( SAP Gateway Service Builder )
Нажимаем "Создать" и вводим название сервиса и его описание.
После подтверждения открывается новый пустой сервис с заранее определенными каталогами. Необходимо создать сущности с требуемыми параметрами. Для начала попробуем вывести таблицу SPFLI. Существует несколько вариантов создания сервиса. Например, создать самим построчно или импортировать из структуры словаря, можно целиком импортировать сервис из другой системы. В данном случае целесообразно импортировать из словаря.
Далее вводим имя сервиса, а также выбираем структуру для импорта. Обратите внимание, что в отличие от ABAP тут есть регистрозависимость, в последствии надо использовать имя сущности именно так, как вы его указали. Это же относится и к атрибутам. Т.е. Field и field это разные поля.
Обратите внимание на галочку Create Default Entity Set. Она означает, что в добавок к сущности для одной записи(выходной структуре), будет создана сущность для набора записей(выходная таблица).
В полученном окне появятся созданные свойства функции. Тут можно их изменить при необходимости. Добавить новые, удалить старые, поменять свойства. В нашем случае стоит заменить тип у поля Fltime на Edm.String(вообще со стрингами меньше всего проблем), т.к. система будет выдавать ошибку при обработке значений согласно функции преобразования для типа указанного в домене этого поля.
Также можно указать некоторые поля как поля фильтра, установив галку в поле Filt. Такие поля можно будет подавать для ограничения выборке при попытке получить Set.(Впрочем, галка необязательно можно подать поле и без нее)
Таким же образом добавим еще одну сущность в выборку. Теперь с таблицей SFLIGHT
Из общего списка выберем только некоторые поля
Когда все готово, сохраняем сервис и генерируем к нему объекты.
Примечание:
Если в будущем мы будем изменять сервис, каждый раз надо генерировать его заново, а также сбросить кэши
После генерации появится ряд объектов, которые можно модифицировать под свои нужды, это классы *_MPC_EXT и *_DPC_EXT.
Примечание:
Классы *_MPC и *_DPC не меняются разработчиком вручную.
Для работы с сущностями нужен *_DPC_EXT. В нем для каждой из сущностей после генерации будет созданы методы *_CREATE_ENTITY - создание записей,
*_UPDATE_ENTITY - обновление записей,
*_DELETE_ENTITY - удаление записей,
*_GET_ENTITY - для получения одной записи, *_GET_ENTITY_SET - для получения списка записей.
Класс *_MPC_EXT - служит для изменения глобальных параметров сервиса.
Проваливаемся в класс ZCL_ZZ_TEST_SERVICE_MPC_EXT и реализуем методы.
Метод _GET_ENTITY получает записи по ключу поэтому на входе имеет таблицу со значениями ключей. Ключами являются поля, которые мы указали как ключи в советующей сущности.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
METHOD entityspfliset_get_entity. DATA(lv_mandt) = it_key_tab[ name = 'Mandt' ]-value. DATA(lv_carrid) = it_key_tab[ name = 'Carrid' ]-value. DATA(lv_connid) = it_key_tab[ name = 'Connid' ]-value. SELECT SINGLE * FROM spfli INTO er_entity WHERE carrid = lv_carrid and connid = lv_connid. ENDMETHOD. METHOD entitysflightset_get_entity. DATA(lv_mandt) = it_key_tab[ name = 'Mandt' ]-value. DATA(lv_carrid) = it_key_tab[ name = 'Carrid' ]-value. DATA(lv_connid) = it_key_tab[ name = 'Connid' ]-value. SELECT SINGLE * FROM sflight INTO er_entity WHERE carrid = lv_carrid and connid = lv_connid. ENDMETHOD. |
Метод _GET_ENTITY_SET выдает список записей и на входе у него не ключ, а список значений для фильтра.(когда дойдем до теста станет понятнее)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
METHOD entitysflightset_get_entityset. DATA(lr_mandt) = VALUE #( it_filter_select_options[ property = 'Mandt' ]-select_options OPTIONAL ). DATA(lr_carrid) = VALUE #( it_filter_select_options[ property = 'Carrid' ]-select_options OPTIONAL ). DATA(lr_connid) = VALUE #( it_filter_select_options[ property = 'Connid' ]-select_options OPTIONAL ). SELECT * FROM sflight INTO TABLE et_entityset WHERE carrid IN lr_carrid AND connid IN lr_connid. ENDMETHOD. METHOD entityspfliset_get_entityset. DATA(lr_mandt) = VALUE #( it_filter_select_options[ property = 'Mandt' ]-select_options OPTIONAL ). DATA(lr_carrid) = VALUE #( it_filter_select_options[ property = 'Carrid' ]-select_options OPTIONAL ). DATA(lr_connid) = VALUE #( it_filter_select_options[ property = 'Connid' ]-select_options OPTIONAL ). SELECT * FROM spfli INTO TABLE et_entityset WHERE carrid IN lr_carrid AND connid IN lr_connid. ENDMETHOD. |
Активация сервиса
Теперь для полноценной работы требуется его регистрация.
1. Перейдем в транзакцию /IWFND/MAINT_SERVICE и добавим сервис
Введем Псевдоним(В общем случае LOCAL, если планируются вызывать сервис из другой системы, то имя даем соответствующее). Существуют более сложные варианты
Жмем ENTER и в открывшемся списке выбираем нужный сервис.
Указываем пакет
Возвращаемся в транзакцию /IWFND/MAINT_SERVICE.
Тут можем найти новый сервис <oData name>_SRV.
Дополнительно надо положить запись ALIAS в настроенный запрос. Иначе есть риск, что при переносе запись потеряется. Не знаю это баг или фича, но если возникает такая проблема, стоит сделать это руками.
Теперь можем перейти в Gateway Client /IWFND/GW_CLIENT
И протестировать
Сервис готов. Далее следует проверить отдельные сервисы.
Тест сервиса
Тестирование осуществляется в транзакции Gateway Client /IWFND/GW_CLIENT
Тестирование метода *_GET_ENTITY
HTTP method - GET
Request URI - прописываем имя СЕРВИСА, и через слеш имя сущности, которую хотим протестировать. В скобках следует указать полный ключ:
/sap/opu/odata/sap/ZZ_TEST_SERVICE_SRV/EntitySpfliSet(Mandt='100',Carrid='AA')
Обратите внимание, что имена полей должны быть записаны с учетом регистра. Если ключ состоит из одного поля, то имя можно опустить. Допустим:
/sap/opu/odata/sap/ZZ_TEST_SERVICE_SRV/XXXXXSet('VALUE').
Результат запуска:
Тестирование метода *_GET_ENTITY_SET
HTTP method - GET
Request URI - прописываем имя СЕРВИСА, и через слеш имя сущности, которую хотим протестировать. Больше можно ничего не вводить, выборка будет без каких либо ограничений.
/sap/opu/odata/sap/ZZ_TEST_SERVICE_SRV/EntitySpfliSet
При необходимости можно задать значения фильтра, которые и будут ограничивать выборку. Делается это путем добавления ?$filter=(условия). Например, в нашем случае.
/sap/opu/odata/sap/ZZ_TEST_SERVICE_SRV/EntitySpfliSet?$filter=(Mandt eq '100' and (Carrid eq 'AA' or Carrid eq 'BB') and Connid eq '0017')
Можно подать несколько значений или пропустить часть.
Результат:
Тестирование метода *_CREATE_ENTITY - создание записей
Данный метод вызывается при помощи запроса POST. Передаваемые данные указываем в виде JSON файла в соответствующем блоке экрана
Код метода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
" METHOD entityspfliset_create_entity. TYPES: BEGIN OF lty_s_data, mandt TYPE string, carrid TYPE string, connid TYPE string, countryfr TYPE string, cityfrom TYPE string, airpfrom TYPE string, countryto TYPE string, cityto TYPE string, airpto TYPE string, fltime TYPE string, END OF lty_s_data. DATA ls_input TYPE lty_s_data. "Получаем входящие данные io_data_provider->read_entry_data( IMPORTING es_data = ls_input ). "Производим какие-либо операции "При необходимости можем что-то вернуть в структуре er_* MOVE-CORRESPONDING ls_input TO er_entity. ENDMETHOD. |
Примечание:
Когда начал тестировать данный метод, получил ошибку при запуске ФМа преобразования. Один из способов лечения - отключить эту программу преобразования.
Тестирование метода *_UPDATE_ENTITY
Указываем и ключ обновляемой записи и новые данные
Тестирование метода *_DELETE_ENTITY
Передаем параметры точно также как в случае с *_GET_ENTITY
Таблица IT_KEY_TAB содержит ключи записи.
Отладка
Ошибки могут быть в ABAP коде, написанного в методе. Для поиска таких, надо поставить внешнюю точку в запускаемом методе и обратиться к сервису.
Второй тип, ошибки при вызова сервиса или какие-то другие внутренние проблемы. Статус ошибки можно увидеть в ответе, если информации мало, можно перейти в транзакцию SAP Gateway Error Log - /IWFND/ERROR_LOG.
В данном случае у нас указаны не все ключевые поля.
Наверное имеется ввиду все таки ZCL_ZZ_TEST_SERVICE_DPC_EXT.
Спасибо, попробовал, все работает