ABAP Modern — RAP, CDS & ABAP Cloud/RAP Fundamentals

Unmanaged RAP — When You Need Full Control

Learn when and how to use unmanaged RAP for wrapping legacy ABAP code, custom persistence, and BAPI integration in modern OData services.

Unmanaged RAP — When You Need Full Control

What You'll Learn

  • When to choose unmanaged over managed RAP
  • The unmanaged save sequence
  • Wrapping existing BAPI logic in a RAP service
  • The interaction phase vs save phase
  • Migration path from unmanaged to managed

When to Use Unmanaged

Managed RAP handles persistence automatically — the framework generates INSERT/UPDATE/DELETE. But what if:

  • You have existing BAPI logic for order processing that's been tested for years?
  • Your data is stored across multiple tables with complex relationships?
  • You need custom locking beyond what managed provides?
  • You're integrating with non-ABAP systems?

Unmanaged RAP gives you the RAP service layer (OData, Fiori, EML) while you keep full control of persistence.

The Behavior Definition

unmanaged implementation in class zbp_i_tm_legacy_order unique;
strict ( 2 );

define behavior for ZI_TM_LegacyOrder alias LegacyOrder
lock master
authorization master ( global )
etag master LastChangedAt
{
  create;
  update;
  delete;

  mapping for ztm_legacy_order corresponding { ... }
}

The only difference from managed: unmanaged instead of managed on the first line.

The Save Sequence

In unmanaged RAP, you implement the save yourself. The framework splits the transaction into two phases:

Interaction Phase — User is editing. Data is in a transactional buffer (memory). No database writes yet.

Save Phase — User clicks Save. The framework calls your save methods to persist the buffer to the database.

CLASS lsc_zi_tm_legacyorder DEFINITION INHERITING FROM
  cl_abap_behavior_saver.

  PROTECTED SECTION.
    METHODS save_modified REDEFINITION.
ENDCLASS.

CLASS lsc_zi_tm_legacyorder IMPLEMENTATION.
  METHOD save_modified.
    " Handle creates
    IF create-legacyorder IS NOT INITIAL.
      LOOP AT create-legacyorder INTO DATA(ls_create).
        INSERT ztm_legacy_order FROM @( CORRESPONDING #( ls_create ) ).
      ENDLOOP.
    ENDIF.

    " Handle updates
    IF update-legacyorder IS NOT INITIAL.
      LOOP AT update-legacyorder INTO DATA(ls_update).
        UPDATE ztm_legacy_order FROM @( CORRESPONDING #( ls_update ) ).
      ENDLOOP.
    ENDIF.

    " Handle deletes
    IF delete-legacyorder IS NOT INITIAL.
      LOOP AT delete-legacyorder INTO DATA(ls_delete).
        DELETE ztm_legacy_order FROM @( CORRESPONDING #( ls_delete-%key ) ).
      ENDLOOP.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

Wrapping a BAPI

TechMart's legacy system has a BAPI for order creation. Wrap it in unmanaged RAP:

METHOD save_modified.
  IF create-legacyorder IS NOT INITIAL.
    LOOP AT create-legacyorder INTO DATA(ls_create).
      " Call the existing BAPI instead of direct SQL
      DATA(ls_header) = VALUE bapi_order_header(
        customer = ls_create-CustomerId
        date     = ls_create-OrderDate
      ).
      
      " Note: In ABAP Cloud, you'd use a released wrapper for the BAPI
      " This is conceptual — actual implementation depends on your system
      CALL FUNCTION 'Z_TM_BAPI_ORDER_CREATE'
        EXPORTING is_header = ls_header
        IMPORTING ev_order_id = DATA(lv_new_id)
        EXCEPTIONS OTHERS = 1.
        
      IF sy-subrc <> 0.
        " Handle error
      ENDIF.
    ENDLOOP.
  ENDIF.
ENDMETHOD.

Managed vs Unmanaged — Decision Matrix

Scenario Use Managed Use Unmanaged
New application, no legacy code Yes
Wrapping existing BAPIs Yes
Simple CRUD on single/few tables Yes
Complex multi-table persistence Yes
Need draft support easily Yes (built-in) Possible but complex
Custom locking requirements Yes
Migrating Classic to RAP Start here, migrate to managed later

Migration Path

Many teams start unmanaged (to wrap legacy code) and migrate to managed over time:

  1. Phase 1: Unmanaged RAP wrapping existing BAPIs → immediate Fiori/OData benefit
  2. Phase 2: Gradually move persistence logic from BAPIs to managed RAP
  3. Phase 3: Full managed RAP with validations, actions, draft

This is TechMart's approach for the legacy order system.

Common Mistakes

  • Starting with unmanaged for new apps — If there's no legacy code to wrap, use managed. It's less code and more framework support.
  • Forgetting the saver class — Unmanaged MUST have a saver class with save_modified. Without it, nothing persists.
  • Calling COMMIT WORK in the saver — The framework handles COMMIT. Your saver does INSERT/UPDATE/DELETE only.
  • Not handling all three operations — Check create, update, AND delete in save_modified. Missing one means that operation silently does nothing.

Key Takeaways

  • Unmanaged RAP gives you the service layer (OData, Fiori, EML) while you control persistence.
  • You implement save_modified in a saver class — handling creates, updates, and deletes to the database.
  • Ideal for wrapping legacy BAPIs and complex persistence scenarios.
  • Start unmanaged for legacy integration, migrate to managed when ready.
  • For new applications with no legacy constraints, always use managed.

Next Lesson

Not all data needs CRUD. In Lesson 18, we'll learn RAP Query — the read-only pattern for analytical views, search results, and data from non-standard sources.