📌 Introduction
In modern SAP development, the RESTful Application Programming Model (RAP) offers a powerful framework for building scalable, maintainable, and service-oriented applications. One of its standout features is Deep Insert, which allows the creation of a root entity along with its associated child entities in a single transactional request.
This blog walks through a real-world implementation of Deep Insert using RAP to create Business Process Exception Management (BPEM) cases via the standard BAPI BAPI_EMMA_CASE_CREATE.
Full source code available on GitHub: https://github.com/bhaskarnagula/bhaskarnagula/tree/RAP
Payload:
POST: https://system_url/sap/opu/odata4/sap/zgen_sb_bpem/srvd/sap/zgen_sd_bpem/0001/$batch
--batch
Content-Type: application/http
Content-Transfer-Encoding: binary
POST BPEMHeader HTTP/1.1
Content-Type: application/json
{
"CCAT": "4",
"MAINOBJTYPE": "Value",
"bpem_objects_flag": true,
"bpem_case_text_flag": true,
"bpem_message_flag": true,
"_BPEMCaseText": [
{
"TDLINE": "td1"
},
{
"TDLINE": "td2"
}
],
"_BPEMObject": [
{
"CELEMNAME": "gjh1",
"REFOBJTYPE": "sf1"
},
{
"CELEMNAME": "gjh2",
"REFOBJTYPE": "sf2"
}
],
"_BPEMMessages": [
{
"MSGID": "000",
"MSGNO": "001"
},
{
"MSGID": "001",
"MSGNO": "000"
}
]
}
--batch--
🧱 Architecture Overview
The solution is structured around the following RAP components:
- – Root Entity: zgen_ce_bpem_header – represents the BPEM case header.
- – Child Entities:
- – zgen_ce_bpem_CASE_TEXT – case text lines.
- – zgen_ce_bpem_MESSAGES – message links.
- – zgen_ce_bpem_object – case objects.
These entities are exposed via the RAP service ZGEN_SD_BPEM.
🧩 Entity Definitions
Each entity is defined using the define custom entity syntax:
Header Entity
define root custom entity zgen_ce_bpem_header {
key BPEM_No : abap.char(10);
CCAT, PRIO, BRGRU, MAINOBJTYPE, MAINOBJKEY, ...
_BPEMObject : composition [1..*] of zgen_ce_bpem_object;
_BPEMCaseText : composition [1..*] of zgen_ce_bpem_CASE_TEXT;
_BPEMMessages : composition [1..*] of zgen_ce_bpem_MESSAGES;
}
Case Text Entity
define custom entity zgen_ce_bpem_CASE_TEXT {
key BPEM_No : abap.char(10);
key TDLINE : abap.char(132);
TDFORMAT : abap.char(2);
_BPEMHeader : association to parent zgen_ce_bpem_header;
}
⚙️ Behavior Definitions
The behavior implementation enables create operations for the root and child entities:
define behavior for zgen_ce_bpem_header alias BPEMHeader {
create;
update;
delete;
association _BPEMCaseText { create; }
association _BPEMMessages { create; }
association _BPEMObject { create; }
}
Child entities are marked as dependent by _BPEMHeader to ensure they are created in context of the parent.
🧠 Business Logic: Deep Insert Flow
The core logic resides in the behavior handler class lhc_BPEMHeader. Here’s how the Deep Insert is orchestrated:
1. Header Data is read from the incoming request and stored in a buffer.
2. Flags (bpem_objects_flag, bpem_case_text_flag, bpem_message_flag) determine whether associated entities are present.
3. Child Entities are processed via their respective cba_ methods if we pass in payload otherwise won’t:
- – cba_Bpemcasetext (if _Bpemcasetext passed in payload then this method will trigger)
- – cba_Bpemmessages (if _Bpemmessages passed in payload then this method will trigger)
- – cba_Bpemobject (if _Bpemobject passed in payload then this method will trigger)
4. Once all required data is buffered, the method call_bapi is invoked.
🔄 BAPI Integration
The BAPI call is wrapped in a utility class ZCL_GEN_UTILITIES:
CALL FUNCTION 'BAPI_EMMA_CASE_CREATE'
EXPORTING case_create = ...
TABLES objects = ..., case_text = ..., messages = ...
IMPORTING case = ...
The result is returned to the RAP framework, and appropriate messages are reported using RAP messaging constructs.
🛡️ Validation & Error Handling
Before creating a new case, the system checks for unresolved cases using the CDS view zgen_i_bpem_details. If a case already exists, a custom error message is returned:
SELECT SINGLE Casenr FROM zgen_i_bpem_details
WHERE mainobjkey = ...
AND status NE '3' AND status NE '4'
🚀 Service Exposure
The RAP service ZGEN_SD_BPEM exposes all entities:
define service ZGEN_SD_BPEM {
expose zgen_ce_bpem_header as BPEMHeader;
expose zgen_ce_bpem_object as BPEMObject;
expose zgen_ce_bpem_CASE_TEXT as BPEMCaseText;
expose zgen_ce_bpem_MESSAGES as BPEMMessages;
}
🧑💻 Developer Tips
- – Use buffering to manage data across multiple child entity handlers.
- – Ensure flag validation before invoking BAPI to avoid partial data issues.
- – Leverage RAP messaging for structured error reporting.
- – Use singleton utility classes for reusable logic.
📚 Conclusion
This implementation showcases the power of RAP’s Deep Insert capability in orchestrating complex transactional operations. By combining RAP behavior definitions, CDS views, and BAPI integration, developers can build robust, scalable, and service-ready applications.
Whether you’re modernizing legacy BAPI-based flows or building new services, RAP provides the tools to do it right.

There’s a quicker, simpler way to do this—stay tuned, I’ll share the update soon!
Visit ABAP RESTful Application Programming Model to explore all articles on ABAP RAP Model.
If you like the content, please subscribe…