📌 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:

  1.    – cba_Bpemcasetext (if _Bpemcasetext passed in payload then this method will trigger)
  2.    – cba_Bpemmessages (if _Bpemmessages passed in payload then this method will trigger)
  3.    – 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.

Git-hub-code-reference

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…

Join 518 other subscribers

Discovering ABAP YouTube Channel