Skip to content

Lesson 14 — RAP Actions, Field Control, and Dynamic Feature Control ​

By the end of Lesson 13, the Reservation Business Object can:

text
create
read
update
delete
default data
validate data
return business messages

Today you add named business operations and state-dependent availability.

The new architecture is:

text
Consumer
   ↓
EML
   ↓
RAP Business Object
   ├─ CRUD
   ├─ determinations
   ├─ validations
   ├─ actions
   └─ feature control
   ↓
Persistence

Lesson information ​

Teacher-led timeAbout 3 hours
Self-practice timeAbout 3 hours
EnvironmentSAP BTP ABAP Trial
PrerequisiteLesson 13
Business ObjectZR_RESERVATION_###
Behavior PoolZBP_R_RESV_###
Runtime test classZCL_RESV_ACTIONS_###
Actionsconfirm, cancel
Main outcomeState-aware behavior

Replace ### with your own suffix.


Learning objectives ​

After the teacher-led part, you should be able to:

  • explain why an action is different from a generic update;
  • define and implement RAP instance actions;
  • return the changed entity with result [1] $self;
  • execute actions with EML;
  • use static field characteristics;
  • use mandatory:create and readonly:update;
  • declare features : instance;
  • implement FOR INSTANCE FEATURES;
  • use operation and field feature constants;
  • request runtime feature information with GET PERMISSIONS;
  • observe feature values changing when Status changes;
  • distinguish feature control from validation and authorization.

1. Why actions? ​

A generic update says:

text
change this field

An action says:

text
perform this business operation

For example:

text
Status N → C

has business meaning:

text
Confirm Reservation

So a consumer should be able to request:

text
confirm

rather than know the internal Status value.


2. What is a RAP action? ​

An action is a non-standard modifying BO operation.

Standard modifying operations are:

text
create
update
delete

Actions are named business operations such as:

text
confirm
cancel
approve
reject
release
close

3. Reservation state model ​

The Reservation status values are:

text
N = New
C = Confirmed
X = Cancelled

Use these transitions:

text
New
 ├─ confirm → Confirmed
 └─ cancel  → Cancelled

Confirmed
 └─ cancel  → Cancelled

Cancelled
 └─ no further state action

4. Availability rules ​

For this lesson:

text
confirm
enabled only when Status = N

cancel
enabled when Status = N or C

For:

text
Status = X

both actions are disabled.


5. Field-control rules ​

Add one static rule:

text
ReservationNo
→ mandatory on create
→ read-only on update

Add one dynamic rule:

text
Fee
CurrencyCode
→ editable while Status = N
→ read-only when Status = C or X

6. Static vs dynamic field control ​

Static control is always the same.

Example:

text
ReservationNo never changes after creation

Dynamic control depends on instance state.

Example:

text
Fee is editable for New Reservations
but read-only after confirmation/cancellation

7. Extend the existing BDEF ​

Open the Behavior Definition for:

text
ZR_RESERVATION_###

Keep all behavior from Lessons 11–13.

Add:

abap
field ( mandatory:create, readonly:update ) ReservationNo;

field ( features : instance ) Fee, CurrencyCode;

action ( features : instance ) confirm result [1] $self;

action ( features : instance ) cancel result [1] $self;

8. What mandatory:create means ​

This characteristic says:

text
a create request must provide ReservationNo

It is a static BO contract rule.


9. What readonly:update means ​

This characteristic says:

text
ReservationNo cannot be changed by a normal update

That fits our business-facing identifier.

The UUID remains the technical key.


10. Why not write a validation for this? ​

A validation could check a missing Reservation Number.

But:

text
mandatory:create

already expresses the rule directly in the behavior contract.

Use field characteristics when they naturally describe access/requiredness.

Use validations for custom business logic.


11. Dynamic field declaration ​

This line:

abap
field ( features : instance ) Fee, CurrencyCode;

means:

The provider will calculate field availability for each instance.

The BDEF declaration enables dynamic control.

The actual answer comes from the Behavior Pool.


12. Action declarations ​

Use:

abap
action ( features : instance ) confirm result [1] $self;

action ( features : instance ) cancel result [1] $self;

Both are:

text
instance actions

because they operate on existing Reservations.


13. What result [1] $self means ​

The action returns exactly one result instance of the same entity type.

Example:

text
input:
Reservation Status = N

confirm result:
same Reservation Status = C

This lets the consumer see the changed state immediately.


14. Generate handler methods ​

Use:

text
Ctrl+1

from the BDEF where ADT offers Quick Fix.

You need methods equivalent to:

text
confirm
cancel
get_instance_features

inside:

text
ZBP_R_RESV_###

15. Action method signatures ​

ADT should generate signatures equivalent to:

abap
METHODS confirm
  FOR MODIFY
  IMPORTING keys FOR ACTION Reservation~confirm
  RESULT result.

METHODS cancel
  FOR MODIFY
  IMPORTING keys FOR ACTION Reservation~cancel
  RESULT result.

Prefer ADT-generated signatures.


16. Feature method signature ​

You also need:

abap
METHODS get_instance_features
  FOR INSTANCE FEATURES
  IMPORTING keys
    REQUEST requested_features
    FOR Reservation
  RESULT result.

This is the provider method that calculates runtime availability.


17. Implement confirm ​

Use provider-side EML:

abap
METHOD confirm.

  MODIFY ENTITIES OF ZR_Reservation_### IN LOCAL MODE
    ENTITY Reservation
      UPDATE FIELDS ( Status )
      WITH VALUE #(
        FOR key IN keys
        ( %tky   = key-%tky
          Status = 'C' )
      )
    FAILED failed
    REPORTED reported.

  READ ENTITIES OF ZR_Reservation_### IN LOCAL MODE
    ENTITY Reservation
      ALL FIELDS
      WITH CORRESPONDING #( keys )
    RESULT DATA(reservations).

  result = VALUE #(
    FOR reservation IN reservations
    ( %tky   = reservation-%tky
      %param = reservation )
  ).

ENDMETHOD.

Replace ###.


18. Why local-mode EML? ​

The action belongs to the BO provider.

It changes:

text
transactional BO state

not the table directly.

Do not write:

abap
UPDATE zresv_###

inside the action.


19. Implement cancel ​

Use the same pattern:

abap
METHOD cancel.

  MODIFY ENTITIES OF ZR_Reservation_### IN LOCAL MODE
    ENTITY Reservation
      UPDATE FIELDS ( Status )
      WITH VALUE #(
        FOR key IN keys
        ( %tky   = key-%tky
          Status = 'X' )
      )
    FAILED failed
    REPORTED reported.

  READ ENTITIES OF ZR_Reservation_### IN LOCAL MODE
    ENTITY Reservation
      ALL FIELDS
      WITH CORRESPONDING #( keys )
    RESULT DATA(reservations).

  result = VALUE #(
    FOR reservation IN reservations
    ( %tky   = reservation-%tky
      %param = reservation )
  ).

ENDMETHOD.

20. Action implementation vs feature control ​

Action implementation answers:

text
What happens when the action runs?

Feature control answers:

text
Should this action currently be available?

Keep those responsibilities separate.


21. What is feature control? ​

Feature control tells consumers whether BO features are currently available.

It can describe:

text
operations
actions
functions
associations
field editability

Lesson 14 focuses on:

text
actions
fields

22. Instance feature control ​

Instance feature control means:

text
the answer depends on the state of a particular BO instance

Example:

text
Reservation A Status = N
confirm enabled

Reservation B Status = C
confirm disabled

23. Implement get_instance_features ​

First read the current Status:

abap
METHOD get_instance_features.

  READ ENTITIES OF ZR_Reservation_### IN LOCAL MODE
    ENTITY Reservation
      FIELDS ( Status )
      WITH CORRESPONDING #( keys )
    RESULT DATA(reservations)
    FAILED failed.

  result = VALUE #(
    FOR reservation IN reservations
    (
      %tky = reservation-%tky

      %features-%action-confirm =
        COND #(
          WHEN reservation-Status = 'N'
          THEN if_abap_behv=>fc-o-enabled
          ELSE if_abap_behv=>fc-o-disabled
        )

      %features-%action-cancel =
        COND #(
          WHEN reservation-Status = 'N'
            OR reservation-Status = 'C'
          THEN if_abap_behv=>fc-o-enabled
          ELSE if_abap_behv=>fc-o-disabled
        )

      %features-%field-Fee =
        COND #(
          WHEN reservation-Status = 'N'
          THEN if_abap_behv=>fc-f-unrestricted
          ELSE if_abap_behv=>fc-f-read_only
        )

      %features-%field-CurrencyCode =
        COND #(
          WHEN reservation-Status = 'N'
          THEN if_abap_behv=>fc-f-unrestricted
          ELSE if_abap_behv=>fc-f-read_only
        )
    )
  ).

ENDMETHOD.

24. Operation vs field constants ​

Remember:

text
fc-o
→ operation/action feature

fc-f
→ field feature

Examples:

abap
if_abap_behv=>fc-o-enabled
if_abap_behv=>fc-o-disabled

and:

abap
if_abap_behv=>fc-f-unrestricted
if_abap_behv=>fc-f-read_only

25. Feature matrix ​

Your implementation should produce:

StatusConfirmCancelFeeCurrencyCode
NEnabledEnabledEditableEditable
CDisabledEnabledRead-onlyRead-only
XDisabledDisabledRead-onlyRead-only

26. Feature control is not authorization ​

Do not confuse:

text
Feature control
→ does the current business state allow this?

Authorization
→ is this user allowed to do this?

Lesson 15 adds authorization.


27. Activate the BO ​

Run:

text
Ctrl+F2

Then:

text
Ctrl+Shift+F3

Verify:

text
BDEF active
Behavior Pool active
Root CDS active

28. Create the runtime test class ​

Create:

text
ZCL_RESV_ACTIONS_###

Implement:

text
IF_OO_ADT_CLASSRUN

The class will prove:

text
New
→ inspect permissions
→ confirm
→ inspect permissions
→ cancel
→ inspect permissions

29. Reserved training number ​

Use:

text
96000001

Make the exercise repeatable.

If an old row exists:

text
discover its UUID
delete it through EML
commit cleanup

Do not use direct SQL modification.


30. Create one New Reservation ​

Create a Reservation with:

text
ReservationNo   = 96000001
CustomerName    = Feature Control Student
CustomerEmail   = feature@example.com
WorkshopCode    = RAP301
ReservationDate = today
Fee             = 250.00
CurrencyCode    = EUR
Status          = omitted

The Lesson 13 determination should produce:

text
Status = N

Commit it.

Save the generated UUID.


31. Verify initial Status ​

Read the instance with EML.

Expected:

text
ReservationNo = 96000001
Status        = N

32. Ask the BO for its features ​

Use EML:

abap
GET PERMISSIONS ONLY INSTANCE FEATURES OF ZR_Reservation_###
  ENTITY Reservation
    FROM VALUE #(
      ( Uuid = uuid )
    )
    REQUEST VALUE #(
      %action-confirm     = if_abap_behv=>mk-on
      %action-cancel      = if_abap_behv=>mk-on
      %field-Fee          = if_abap_behv=>mk-on
      %field-CurrencyCode = if_abap_behv=>mk-on
    )
  RESULT DATA(permissions_new)
  FAILED DATA(failed_permissions_new)
  REPORTED DATA(reported_permissions_new).

Output the result.


33. Expected features for N ​

Expect conceptually:

text
confirm      enabled
cancel       enabled
Fee          unrestricted
CurrencyCode unrestricted

This proves your feature handler is active.


34. Why GET PERMISSIONS is valuable ​

The consumer asks the BO:

text
What is available right now?

The consumer does not duplicate:

text
IF Status = ...

logic.

The BO remains the source of truth.


35. Execute confirm ​

Use:

abap
MODIFY ENTITIES OF ZR_Reservation_###
  ENTITY Reservation
    EXECUTE confirm
      FROM VALUE #(
        ( Uuid = uuid )
      )
    RESULT DATA(confirm_result)
  FAILED DATA(failed_confirm)
  REPORTED DATA(reported_confirm).

Inspect:

text
RESULT
FAILED
REPORTED

36. Action result before commit ​

Because the action returns:

text
[1] $self

the result should show:

text
Status = C

inside the current RAP transaction.


37. Commit confirm ​

Use:

abap
COMMIT ENTITIES
  RESPONSE OF ZR_Reservation_###
    FAILED DATA(failed_confirm_commit)
    REPORTED DATA(reported_confirm_commit).

Verify success.


38. Ask for features again ​

Run the same:

text
GET PERMISSIONS

request.

Expected for:

text
Status = C

is:

text
confirm      disabled
cancel       enabled
Fee          read-only
CurrencyCode read-only

39. What changed? ​

The consumer did not change its feature logic.

The BO returned a different result because:

text
Status changed from N to C

That is dynamic feature control.


40. Execute cancel ​

Use:

abap
MODIFY ENTITIES OF ZR_Reservation_###
  ENTITY Reservation
    EXECUTE cancel
      FROM VALUE #(
        ( Uuid = uuid )
      )
    RESULT DATA(cancel_result)
  FAILED DATA(failed_cancel)
  REPORTED DATA(reported_cancel).

Expected action result:

text
Status = X

Commit it.


41. Final feature request ​

Request permissions again.

For:

text
Status = X

expect:

text
confirm      disabled
cancel       disabled
Fee          read-only
CurrencyCode read-only

42. Verify with F8 ​

Open:

text
ZR_RESERVATION_###

Press:

text
F8

Find:

text
96000001

Expected:

text
Status = X

You have now checked the BO using:

text
action result
GET PERMISSIONS
CDS Data Preview

43. Check static field control ​

The BDEF declares:

abap
field ( mandatory:create, readonly:update ) ReservationNo;

Use ADT/F2 on the BDEF-derived update type where useful.

As a repair exercise, temporarily attempt to include:

text
ReservationNo

in an external EML update.

Observe that the BO contract does not allow a normal update of this field.

Restore the valid source.


44. Feature control vs validation ​

Use:

text
Can the consumer edit Fee?
→ field control

Is Fee > 0?
→ validation

These solve different problems.


45. Feature control vs action ​

Use:

text
Is confirm currently available?
→ feature control

What does confirm do?
→ action implementation

46. Why actions improve the API ​

Without actions, every consumer must understand:

text
which Status values exist
which transitions are legal
what future side effects happen

With actions, the business command is stable:

text
confirm
cancel

Later you can add more internal logic without changing the consumer command.


47. Common mistake — direct SQL in actions ​

Do not write:

abap
UPDATE zresv_###

Actions should participate in:

text
transactional buffer
validations
save sequence
messages
ETag handling

Use local-mode EML.


48. Common mistake — wrong feature constant family ​

Use:

text
fc-o

for actions/operations.

Use:

text
fc-f

for fields.


49. Common mistake — dynamic code for a static rule ​

Do not implement:

text
ReservationNo read-only after create

in get_instance_features.

It never depends on current state.

Use:

text
readonly:update

instead.


50. Common mistake — implementation without BDEF declaration ​

If you want dynamic feature control, the BDEF must declare:

text
features : instance

for that action/field.

The feature method alone is not enough.


51. Common mistake — feature control as authorization ​

Do not use this lesson's feature method to answer:

text
Who is the user?
Which role do they have?

That is Lesson 15.


52. Knowledge check ​

1. What is a RAP action? ​

2. Why is confirm an action rather than just a Status update? ​

3. What does result [1] $self mean? ​

4. What does mandatory:create mean? ​

5. What does readonly:update mean? ​

6. What is instance feature control? ​

7. Why do Fee and CurrencyCode use dynamic feature control? ​

8. What does FOR INSTANCE FEATURES do? ​

9. Why does the feature handler read Status? ​

10. What is %features-%action-confirm? ​

11. What is %features-%field-Fee? ​

12. What is the difference between fc-o and fc-f? ​

13. What does GET PERMISSIONS do? ​

14. Why is feature control not authorization? ​

15. Why do the action methods use IN LOCAL MODE? ​


53. Teacher-led completion checklist ​


54. End-of-day mental model ​

text
Action
→ named business operation

Static field control
→ same rule for every instance

Instance feature control
→ availability depends on BO state

GET PERMISSIONS
→ consumer asks what is available

FOR INSTANCE FEATURES
→ provider calculates the answer

Runtime flow:

text
Status N
   ↓
GET PERMISSIONS
   ↓
Confirm enabled
Cancel enabled
Fee editable
   ↓
EXECUTE confirm
   ↓
Status C
   ↓
GET PERMISSIONS
   ↓
Confirm disabled
Cancel enabled
Fee read-only
   ↓
EXECUTE cancel
   ↓
Status X
   ↓
both actions disabled

Lesson 15 adds the next question:

text
The business state allows the operation,
but is this user authorized?