agentsclimarketplace

Sap rap comprehensive

Skill efeumutaslan/SAP-SKILLS/skills/sap-rap-comprehensive

23 SAP development skills for Claude Code — ABAP, RAP, CAP, Fiori, BTP, HANA, S/4HANA, Integration Suite and more. Agent Skills Specification compatible.

Install
npx -y skills add efeumutaslan/SAP-SKILLS --skill sap-rap-comprehensive

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

SAP RAP (RESTful Application Programming Model) comprehensive development skill. Use when creating RAP business objects, writing BDEF/CDS view entities, implementing validations/ determinations/actions, handling drafts, writing EML, or extending standard RAP BOs. If the user mentions RAP, BDEF, behavior definition, CDS view entity, EML, managed/unmanaged BO, or service binding, use this skill. Covers BTP, S/4HANA Cloud, and On-Premise.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

14.5 KB, as published. Nobody here has run it

SAP RAP — RESTful Application Programming Model

Related Skills

  • sap-s4hana-extensibility — Extending standard SAP RAP BOs
  • sap-security-authorization — RAP authorization patterns
  • sap-testing-quality — RAP test doubles in depth

Quick Start

RAP BO in 5 artifacts:

1. Database Table     → ZTAB_TRAVEL
2. CDS View Entity    → ZI_Travel (interface, root)
3. Behavior Definition → ZI_Travel (managed, draft)
4. Behavior Impl.     → ZBP_I_Travel (handler + saver)
5. Service Definition  → ZSD_Travel → Service Binding (V4)

Minimum BDEF (managed with draft):

managed implementation in class zbp_i_travel unique;
strict ( 2 );
with draft;

define behavior for ZI_Travel alias Travel
persistent table ztab_travel
draft table zdraft_travel
etag master LocalLastChangedAt
lock master total etag LastChangedAt
authorization master ( global, instance )
{
  field ( readonly ) TravelUUID;
  field ( mandatory ) AgencyID, CustomerID;

  create; update; delete;

  determination SetStatusNew on modify { create; }
  validation ValidateDates on save { field BeginDate, EndDate; }
  action ( features : instance ) AcceptTravel result [1] $self;

  draft action Resume;
  draft action Edit;
  draft action Activate optimized;
  draft action Discard;
  draft determine action Prepare;

  mapping for ztab_travel corresponding;
}

Core Concepts

RAP Architecture Layers

┌─ Service Layer ──────────────────────────────┐
│  Service Definition → Service Binding (V2/V4) │
├─ BO Projection Layer ────────────────────────┤
│  CDS Projection View (C_*) + Projection BDEF  │
├─ BO Interface Layer ─────────────────────────┤
│  CDS View Entity (I_*) + Behavior Definition   │
│  + Behavior Implementation (Handler/Saver)     │
├─ Data Layer ─────────────────────────────────┤
│  Database Tables / CDS Abstract Entities       │
└──────────────────────────────────────────────┘

Implementation Types

TypeWhen to UseKey Difference
ManagedNew greenfield developmentFramework handles CRUD + persistence
UnmanagedWrapping legacy (BAPIs, FMs)Developer handles all persistence
Managed + Unmanaged SaveManaged CRUD but custom saveFramework CRUD, you handle DB write
Managed + Additional SaveManaged save + extra side-effectsFramework saves, you do extra work

CDS View Entity — Root with Child

@AccessControl.authorizationCheck: #CHECK
define root view entity ZI_Travel
  as select from ztab_travel
  composition [0..*] of ZI_Booking as _Booking
{
  key travel_uuid       as TravelUUID,
      travel_id         as TravelID,
      agency_id         as AgencyID,
      customer_id       as CustomerID,
      begin_date        as BeginDate,
      end_date          as EndDate,
      @Semantics.amount.currencyCode: 'CurrencyCode'
      total_price       as TotalPrice,
      currency_code     as CurrencyCode,
      overall_status    as OverallStatus,
      @Semantics.user.createdBy: true
      created_by        as CreatedBy,
      @Semantics.systemDateTime.createdAt: true
      created_at        as CreatedAt,
      @Semantics.user.lastChangedBy: true
      last_changed_by   as LastChangedBy,
      @Semantics.systemDateTime.lastChangedAt: true
      last_changed_at   as LastChangedAt,
      @Semantics.systemDateTime.localInstanceLastChangedAt: true
      local_last_changed_at as LocalLastChangedAt,

      _Booking
}

Common Patterns

Pattern 1: Validation (on save)

METHOD validateDates.
  READ ENTITIES OF zi_travel IN LOCAL MODE
    ENTITY Travel
    FIELDS ( BeginDate EndDate )
    WITH CORRESPONDING #( keys )
    RESULT DATA(lt_travels).

  LOOP AT lt_travels INTO DATA(ls_travel).
    IF ls_travel-BeginDate > ls_travel-EndDate.
      APPEND VALUE #( %tky = ls_travel-%tky ) TO failed-travel.
      APPEND VALUE #( %tky = ls_travel-%tky
        %msg = new_message_with_text(
          severity = if_abap_behv_message=>severity-error
          text     = 'Begin date must be before end date' )
        %element-BeginDate = if_abap_behv=>mk-on
        %element-EndDate   = if_abap_behv=>mk-on
      ) TO reported-travel.
    ENDIF.
  ENDLOOP.
ENDMETHOD.

Pattern 2: Determination (on modify)

METHOD setStatusNew.
  READ ENTITIES OF zi_travel IN LOCAL MODE
    ENTITY Travel
    FIELDS ( OverallStatus )
    WITH CORRESPONDING #( keys )
    RESULT DATA(lt_travels).

  MODIFY ENTITIES OF zi_travel IN LOCAL MODE
    ENTITY Travel
    UPDATE FIELDS ( OverallStatus )
    WITH VALUE #( FOR travel IN lt_travels
      WHERE ( OverallStatus IS INITIAL )
      ( %tky = travel-%tky  OverallStatus = 'O' ) ).  " Open
ENDMETHOD.

Pattern 3: Action with Result

METHOD acceptTravel.
  MODIFY ENTITIES OF zi_travel IN LOCAL MODE
    ENTITY Travel
    UPDATE FIELDS ( OverallStatus )
    WITH VALUE #( FOR key IN keys
      ( %tky = key-%tky  OverallStatus = 'A' ) ).  " Accepted

  READ ENTITIES OF zi_travel IN LOCAL MODE
    ENTITY Travel
    ALL FIELDS
    WITH CORRESPONDING #( keys )
    RESULT DATA(lt_travels).

  result = VALUE #( FOR travel IN lt_travels
    ( %tky = travel-%tky  %param = travel ) ).
ENDMETHOD.

Pattern 4: Instance Feature Control

METHOD get_instance_features.
  READ ENTITIES OF zi_travel IN LOCAL MODE
    ENTITY Travel
    FIELDS ( OverallStatus )
    WITH CORRESPONDING #( keys )
    RESULT DATA(lt_travels).

  result = VALUE #( FOR travel IN lt_travels
    ( %tky = travel-%tky
      %action-AcceptTravel = COND #(
        WHEN travel-OverallStatus = 'A'
        THEN if_abap_behv=>fc-o-disabled    " Already accepted
        ELSE if_abap_behv=>fc-o-enabled )
      %action-RejectTravel = COND #(
        WHEN travel-OverallStatus = 'X'
        THEN if_abap_behv=>fc-o-disabled    " Already rejected
        ELSE if_abap_behv=>fc-o-enabled )
    ) ).
ENDMETHOD.

Pattern 5: Authorization (Global + Instance)

" Global authorization: Can user create at all?
METHOD get_global_authorizations.
  IF requested_authorizations-%create = if_abap_behv=>mk-on.
    AUTHORITY-CHECK OBJECT 'Z_TRAVEL' ID 'ACTVT' FIELD '01'.
    result-%create = COND #(
      WHEN sy-subrc = 0 THEN if_abap_behv=>auth-allowed
      ELSE if_abap_behv=>auth-unauthorized ).
  ENDIF.
ENDMETHOD.

" Instance authorization: Can user update THIS travel?
METHOD get_instance_authorizations.
  READ ENTITIES OF zi_travel IN LOCAL MODE
    ENTITY Travel FIELDS ( AgencyID ) WITH CORRESPONDING #( keys )
    RESULT DATA(lt_travels).

  LOOP AT lt_travels INTO DATA(ls_travel).
    AUTHORITY-CHECK OBJECT 'Z_TRAVEL'
      ID 'ACTVT' FIELD '02'
      ID 'Z_AGNCY' FIELD ls_travel-AgencyID.
    DATA(lv_update) = COND #(
      WHEN sy-subrc = 0 THEN if_abap_behv=>auth-allowed
      ELSE if_abap_behv=>auth-unauthorized ).

    APPEND VALUE #( %tky = ls_travel-%tky
      %update = lv_update
      %action-AcceptTravel = lv_update
    ) TO result.
  ENDLOOP.
ENDMETHOD.

Pattern 6: EML (Entity Manipulation Language)

" Create
MODIFY ENTITIES OF zi_travel
  ENTITY Travel
  CREATE FIELDS ( AgencyID CustomerID BeginDate EndDate )
  WITH VALUE #( (
    %cid       = 'CID_1'
    AgencyID   = '70001'
    CustomerID = '100000'
    BeginDate  = cl_abap_context_info=>get_system_date( )
    EndDate    = cl_abap_context_info=>get_system_date( ) + 14
  ) )
  MAPPED DATA(ls_mapped)
  FAILED DATA(ls_failed)
  REPORTED DATA(ls_reported).

" Read
READ ENTITIES OF zi_travel
  ENTITY Travel
  ALL FIELDS
  WITH VALUE #( ( TravelUUID = lv_uuid ) )
  RESULT DATA(lt_result).

" Commit
COMMIT ENTITIES
  RESPONSE OF zi_travel
  FAILED DATA(ls_commit_failed)
  REPORTED DATA(ls_commit_reported).

Pattern 7: Draft Handling Flow

[New]
  → Edit → [Draft created in draft table]
    → Modify fields (auto-saved to draft table)
      → Prepare (runs validations on draft)
        → Activate (moves draft → active table, runs on-save validations)

[Existing Active]
  → Edit → [Copy to draft table, lock active]
    → Modify → Prepare → Activate

[Discard] → Delete draft, unlock active
[Resume] → Continue editing existing draft

Draft table structure: Same as active table + admin fields (%is_draft, draftentityoperationcode, etc.)

Error Catalog

ErrorCauseFix
"Entity not modifiable"Missing update in BDEFAdd update; to behavior definition
"Draft table does not exist"Draft table not createdCreate DDIC table matching draft table name in BDEF
CDS activation "composition invalid"Child not defined as root or composition mismatchChild must NOT be root; check composition [0..*] of syntax
"Determination not triggered"Wrong trigger event (on modify vs on save)Verify trigger: on modify { create; } vs on save { field X; }
"Authorization check failed"Missing AUTHORITY-CHECK or wrong objectImplement get_global_authorizations / get_instance_authorizations
BDEF activation "strict mode"Using deprecated syntax in strict ( 2 )Use current syntax; check ADT error message for guidance
"%cid not found in mapped"Create-by-association without matching %cid_refEnsure parent %cid matches child %cid_ref in EML
"Lock conflict" on editAnother user has active draftCheck draft table for existing draft; use Resume if same user
"Feature control not working"Method signature mismatchUse exact parameter types from handler class interface
"etag mismatch"Stale data (concurrent modification)Reload data and retry; check etag field definition

Performance Tips

  • Use IN LOCAL MODE in handler methods to skip authorization re-checks
  • Read only needed fields: FIELDS ( Field1 Field2 ) not ALL FIELDS
  • Avoid N+1 queries: batch-read entities, don't loop-and-read
  • Use %control to detect which fields were actually sent by the client
  • Keep validations focused: one validation per business rule
  • Use on modify determinations for immediate feedback, on save for expensive checks

BTP vs S/4HANA Differences

AspectBTP ABAP EnvironmentS/4HANA Cloud/On-Prem
strict modestrict ( 2 ) requiredstrict ( 1 ) or none
Available APIsOnly released (C1/C2)All (on-prem), released (cloud)
ABAP versionABAP Cloud onlyCloud or Classic
Service bindingOData V4 defaultV2 and V4 available
DraftStandardStandard
Extend SAP BOVia released extension pointsFull access (on-prem)

Bundled Resources

FileWhen to Read
references/rap-complete-guide.mdFull RAP reference with all patterns
references/bdef-syntax-reference.mdComplete BDEF syntax reference
references/eml-cheatsheet.mdEML statement quick reference
templates/managed-bo.cdsComplete managed RAP BO template
templates/handler-class.abapHandler class implementation template
templates/test-class.abapRAP unit test template with CL_BOTD

Gotchas

  • Managed vs. Unmanaged save: Managed RAP handles INSERT/UPDATE/DELETE automatically; if you need custom save logic, use managed with additional save or managed with unmanaged save — don't fight the framework
  • Draft and non-draft mismatch: If root entity has draft, ALL compositions in the BO must also have draft — partial draft is not allowed
  • EML in non-RAP context: EML (MODIFY ENTITIES OF ...) can only be used inside RAP behavior implementations or with IN LOCAL MODE / PRIVILEGED ACCESS — not in arbitrary ABAP programs
  • Late numbering gotcha: With late numbering, %pid (preliminary ID) is only valid within the same LUW — never persist it; map to final key in adjust_numbers
  • Authorization timing: Global authorization is checked FIRST, then instance authorization — if global auth fails, instance auth never runs
  • CDS view vs. view entity: RAP requires CDS view ENTITIES (define root view entity), not classic CDS views (define view) — migration needed for legacy CDS
  • Determination on modify vs. on save: on modify runs immediately and can set fields visible to user; on save runs during finalize — choose based on UX needs
  • Strict mode levels: strict(2) is recommended for new BOs; it enforces additional validations and will be required in future releases

Validation Workflow

After creating or modifying a RAP BO, validate completeness:

bash scripts/validate-rap-bo.sh ./src

RAP BO checklist:

  • Root view entity defined with define root view entity
  • BDEF has authorization control (master/dependent)
  • ETag field defined for concurrency control
  • Draft table defined (if draft enabled)
  • Service definition and binding created
  • At least one unit test class exists

MCP Server Integration

{
  "mcpServers": {
    "vibing-steampunk": {
      "command": "npx", "args": ["-y", "vibing-steampunk"],
      "env": { "SAP_HOST": "https://your-system.abap.hana.ondemand.com",
               "SAP_USER": "YOUR_USER", "SAP_PASSWORD": "YOUR_PASSWORD" }
    }
  }
}
  • Vibing Steampunk: Read/write BDEF, CDS, handler classes directly on SAP system via ADT

Source Documentation

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.