Модуль в этой статье: Integration Flow Helper
Получатель OData в SAP CPI: $select, $filter, $expand и $orderby без опечаток
Параметры запроса получателя OData в SAP CPI: $select, $filter, $expand, $orderby и $top на примерах, отличия V2 от V4 и ошибки, из-за которых возникает HTTP 400.

Адаптер-получатель OData в SAP CPI превращает Resource Path и строку параметров запроса в вызов сервиса OData, например API SAP S/4HANA. Параметры запроса определяют, какие поля, строки и связанные сущности вернутся, и одного неправильно написанного имени свойства достаточно, чтобы сервис отклонил вызов.
В этой статье на примере разобраны $select, $filter, $expand и $orderby, отличия OData V2 от V4, которые многих сбивают с толку, и способы держать имена правильными.
Где в получателе OData задаются параметры запроса
На вкладке Processing адаптера вы выбираете операцию, а затем задаёте Resource Path — вызываемый entity set или сущность — и Query Options, то есть всё, что идёт после ? в URL. Мастер запросов адаптера может собрать и то и другое по метаданным сервиса и сохраняет эти метаданные, файл EDMX, в ресурсах iFlow.
Параметры запроса могут содержать выражения Simple, поэтому значения могут браться из сообщения, например $filter=SoldToParty eq '${property.customerId}'. Пример ниже читает заказы на продажу с позициями из API_SALES_ORDER_SRV, сервиса OData V2:
Resource Path: A_SalesOrder
Query Options: $select=SalesOrder,SoldToParty,CreationDate,to_Item/SalesOrderItem,to_Item/Material
&$expand=to_Item
&$filter=SoldToParty eq '${property.customerId}' and CreationDate ge datetime'2026-01-01T00:00:00'
&$orderby=CreationDate desc
&$top=50В адаптере параметры запроса записываются одной строкой; здесь они разбиты только для удобства чтения.
Четыре параметра по очереди
| Параметр | Что делает | Пример |
|---|---|---|
$select | Возвращает только указанные свойства, благодаря чему ответы остаются небольшими | $select=SalesOrder,SoldToParty |
$filter | Возвращает только строки, удовлетворяющие условию | $filter=SalesOrderType eq 'OR' |
$expand | Включает связанные сущности через навигационное свойство | $expand=to_Item |
$orderby | Сортирует строки, по умолчанию по возрастанию | $orderby=CreationDate desc |
$top и $skip ограничивают результат и разбивают его на страницы. В OData V2 свойство раскрытой сущности выбирается через путь, как в to_Item/Material, и навигационное свойство тоже должно быть указано в $expand.
У $filter свои операторы: eq, ne, gt, ge, lt, le, соединённые через and, or и not. Текстовые значения заключаются в одинарные кавычки, а даты нужно записывать в литеральной форме, которую ожидает версия сервиса.
OData V2 и V4 пишутся по-разному
Адаптер OData поддерживает обе версии, и многие API SAP существуют в обеих. Копирование запроса из одной версии в другую — частый источник ошибок:
OData V2: $inlinecount=allpages
$filter=substringof('Smith',CustomerName)
$filter=CreationDate ge datetime'2026-01-01T00:00:00'
OData V4: $count=true
$filter=contains(CustomerName,'Smith')
$filter=CreatedAt ge 2026-01-01T00:00:00Z
$expand=_Item($select=Product,Quantity)- Подсчёт строк:
$inlinecount=allpagesв V2,$count=trueв V4. - Поиск внутри текста:
substringof('Smith',CustomerName)в V2,contains(CustomerName,'Smith')в V4. Обратите внимание: аргументы идут в обратном порядке. - Даты: V2 пишет
datetime'2026-01-01T00:00:00'; V4 пишет значение без префикса. - Раскрытые свойства: V2 выбирает их через путь; V4 вкладывает параметры внутрь expand, как в
$expand=_Item($select=Product,Quantity).
Опечатки, из-за которых возникает HTTP 400
Когда параметр запроса неверен, сервис обычно отвечает HTTP 400 и указывает часть, которую не смог разобрать. Причины почти всегда одни и те же:
- Неверный регистр: имена OData чувствительны к регистру, поэтому
soldToParty— неSoldToParty. - Entity set там, где нужно навигационное свойство:
$expand=A_SalesOrderItemвместо$expand=to_Item. - Свойство, которое есть в другой сущности или только в другой версии сервиса.
- Нет кавычек вокруг текстовых значений, или литерал даты V2 отправлен в сервис V4.
- Проблема с разделителями: параметры соединяются через
&, а имя каждого параметра начинается с$.
Выражения добавляют собственный риск: если ${property.customerId} пусто, фильтр превращается в SoldToParty eq '' и молча не возвращает строк вместо ошибки. В статье о выражениях Simple объясняется, как читаются такие значения.
Держите запрос и сервис в согласии
- Считайте EDMX из ресурсов iFlow источником истины для имён и обновляйте его, когда меняется сервис.
- Выбирайте только те поля, которые маппите; меньший ответ быстрее и его проще читать в trace.
- Для больших выборок используйте опцию адаптера для постраничной обработки вместо одного огромного ответа.
- Проверьте запрос хотя бы раз с теми самыми значениями, которые подставит в него реальное сообщение.
Вызываете REST API, а не сервис OData? Получатель HTTP разобран в статье о Postman и OpenAPI.
Чем помогает Kitegra
Расширение браузера Kitegra читает EDMX, который ваш iFlow уже содержит для канала-получателя OData. В дизайнере оно по этому EDMX подсказывает Resource Path, а также имена свойств и навигации для $select, $filter, $expand и $orderby, так что имена вы выбираете, а не набираете.
Его панель lint отмечает имена OData, которых нет в EDMX, а также незакрытые ${ и headers или свойства, которые ничто не задаёт. Если канал не получает подсказок, проверьте, что его EDMX лежит в ресурсах iFlow. Расширение никогда не сохраняет, не развёртывает и не редактирует содержимое iFlow, а ваш tenant меняется только тогда, когда вы нажимаете одно из четырёх названных действий, и их можно отключить.
Чтобы проверить, что на самом деле ответил сервис OData, трассируйте сообщение шаг за шагом и посмотрите тело после вызова.
Без аккаунта Kitegra расширение работает на 5 iFlow в каждом модуле. Тариф Free охватывает 50, Starter — 100, Pro — 300; в Business ограничений нет. Сравните тарифы.
Попробуйте в следующем iFlow
Узнайте, что делает Kitegra в дизайнере SAP Integration Suite, или посмотрите его рядом с другими расширениями Kitegra для Chrome.
Частые вопросы
Куда писать $filter в адаптере OData SAP CPI?
В поле Query Options на вкладке Processing канала-получателя, вместе с другими параметрами, например $select=SalesOrder&$filter=SalesOrderType eq 'OR'.
Можно ли использовать header или свойство внутри фильтра OData?
Да. Параметры запроса принимают выражения Simple, например $filter=SoldToParty eq '${property.customerId}'. Если значение пустое, фильтр не вернёт строк, поэтому проверьте его заранее.
Чем $inlinecount отличается от $count?
$inlinecount=allpages относится к OData V2; $count=true — форма OData V4. Оба возвращают вместе с результатом общее число строк, удовлетворяющих условию.
Почему substringof не работает в моём сервисе?
substringof есть только в OData V2. Сервис OData V4 использует contains(Property,'text') с аргументами в обратном порядке.
Почему сервис отвечает HTTP 400?
Обычно потому, что имени из запроса нет в этой сущности — часто из-за регистра, из-за путаницы навигационного свойства с entity set или из-за синтаксиса другой версии OData.
Где SAP CPI хранит метаданные OData?
Мастер запросов сохраняет файл EDMX сервиса в ресурсах iFlow. Обновляйте его при изменении сервиса, чтобы имена оставались правильными.