<!-- https://abap2ui5.github.io/docs/cookbook/eml_cds_sql/rap -->

# RAP

abap2UI5 is OData/RAP-agnostic — it doesn't care where data lives. You keep all your RAP logic (validations, determinations, actions, draft tables); only the UI layer is different — instead of a Fiori Elements frontend, you build the view in ABAP.

## RAP is a Programming Model — abap2UI5 is Not

**RAP (RESTful Application Programming Model)** is a full-stack programming model. It prescribes how you design, expose, and consume business objects: you define entities with CDS views, declare their behavior in Behavior Definitions (BDEFs), implement handlers in Behavior Implementation classes, and expose everything as an OData V4 service consumed by a Fiori Elements frontend. Every layer is part of the model.

**abap2UI5 is not a programming model.** It is a UI rendering library — a single ABAP interface your class implements. It has no opinion on how you structure your data, which access layer you use, or how your business logic is organized. There is no CDS requirement, no BDEF, no OData service. abap2UI5 simply calls your `main` method on each user interaction and renders whatever view you return.

This distinction matters: RAP defines the architecture *around* your application. abap2UI5 only defines how the UI is built *inside* your ABAP class.

## abap2UI5 is Agnostic

Because abap2UI5 imposes no access layer, you pick whatever fits:

| Access Layer | Works in abap2UI5? |
|---|---|
| ABAP SQL (`SELECT`, `INSERT`, …) | ✅ |
| CDS Views (VDM, custom) | ✅ |
| EML (`READ ENTITIES`, `MODIFY ENTITIES`) | ✅ |
| Function modules, BAPIs | ✅ |
| RAP actions called via EML | ✅ |
| Direct table access | ✅ |

Nothing is excluded. The abap2UI5 controller is a plain ABAP class — any statement that is valid in ABAP is valid there.

## Using RAP Functionality from Outside

When you call EML from inside the RAP framework (e.g., from a Behavior Implementation), the framework enforces its own rules: no explicit `COMMIT WORK`, no direct database modifications, controlled side effects.

abap2UI5 runs **outside** the RAP framework. This means all RAP restrictions that apply inside the framework do not apply here. You call EML freely:

```abap
READ ENTITIES OF i_salesordertp
  ENTITY salesorder
  ALL FIELDS WITH VALUE #( ( SalesOrder = `0000000001` ) )
  RESULT DATA(lt_result).
```

```abap
MODIFY ENTITIES OF i_salesordertp
  ENTITY salesorder
  CREATE FIELDS ( salesordertype salesorganization soldtoparty )
  WITH VALUE #( ( %cid = `001` %data = VALUE #( ... ) ) )
  MAPPED DATA(ls_mapped)
  FAILED DATA(ls_failed)
  REPORTED DATA(ls_reported).

COMMIT ENTITIES BEGIN
  RESPONSE OF i_salesordertp
  FAILED DATA(ls_save_failed)
  REPORTED DATA(ls_save_reported).
COMMIT ENTITIES END.
```

The explicit `COMMIT ENTITIES` is required — and fully permitted — because you are not inside a RAP handler. The same applies to reading CDS views, calling RAP actions, or accessing draft tables directly.

::: tip
Running outside the RAP framework gives you more control: you decide when to commit, how to handle errors, and how to combine multiple business object operations in one user interaction.
:::

<!-- samples:start (generated by scripts/link-samples.mjs — do not edit) -->

## Working Samples

Complete apps from the [sample catalog](https://abap2ui5.github.io/playground/samples/)
that use what this page describes. Each is a single class in [abap2UI5/samples](https://github.com/abap2UI5/samples)
unless its row names another of the three sample repositories — pull that repository with
[abapGit](https://abapgit.org) and start the class with `?app_start=<class>`.

| Sample | Class |
|---|---|
| Read a Travel — reads one instance by its key - a missing key comes back in FAILED, not as an exception | [`Z2UI5_CL_SMPS_APP_001`](https://github.com/abap2UI5/samples-stack/blob/main/src/03/z2ui5_cl_smps_app_001.clas.abap) · [samples-stack](https://github.com/abap2UI5/samples-stack), branch `03-rap` |
| Create a Travel — MODIFY ... CREATE, key from MAPPED | [`Z2UI5_CL_SMPS_APP_002`](https://github.com/abap2UI5/samples-stack/blob/main/src/03/z2ui5_cl_smps_app_002.clas.abap) · [samples-stack](https://github.com/abap2UI5/samples-stack), branch `03-rap` |
| Update a Travel — changes single fields of one instance - UPDATE FIELDS names what may be touched | [`Z2UI5_CL_SMPS_APP_003`](https://github.com/abap2UI5/samples-stack/blob/main/src/03/z2ui5_cl_smps_app_003.clas.abap) · [samples-stack](https://github.com/abap2UI5/samples-stack), branch `03-rap` |
| Delete a Travel — deletes one instance - MODIFY ... DELETE FROM | [`Z2UI5_CL_SMPS_APP_004`](https://github.com/abap2UI5/samples-stack/blob/main/src/03/z2ui5_cl_smps_app_004.clas.abap) · [samples-stack](https://github.com/abap2UI5/samples-stack), branch `03-rap` |
| Manage Travels, the Complete App — 01-04 plus EXECUTE and COMMIT ENTITIES RESPONSE OF | [`Z2UI5_CL_SMPS_APP_005`](https://github.com/abap2UI5/samples-stack/blob/main/src/03/z2ui5_cl_smps_app_005.clas.abap) · [samples-stack](https://github.com/abap2UI5/samples-stack), branch `03-rap` |

<!-- samples:end -->
