[explore] Exercises 9: External API-based Access to the RAP BO with the Entity Manipulation Language (EML)
So far, the Entity Manipulation Language (EML) was used in the so-called IN LOCAL MODE
to implement the transactional behavior of the Travel BO entity in the behavior pool.
In the previous exercise, you've written an ABAP Unit test for your Travel BO using EML. (see Exercise 8).
In the present exercise, you will explore how to use EML to consume - i.e. read, update, create, and delete - instances of the Travel BO entity from outside the RAP context. An ABAP class containing sample EML-based access implementations for the Travel BO entity is provided for the purpose.
This exercise is all about exploring and better understanding EML. Follow the instructions below - and feel free to copy and modify the sample implementations as you like.
- 9.1 - Create the ABAP Class
- 9.2 - READ a Travel BO Entity Instance
- 9.3 - UPDATE a Travel BO Entity Instance
- 9.4 - CREATE a Travel_ BO Entity Instance
- 9.5 - DELETE a Travel BO Entity Instance
- 9.6 - ACTIVATE a Draft Travel BO Entity Instance
- 9.7 - DISCARD a Draft Travel BO Entity Instance
- 9.8 - Play Around with EML
- Summary
Reminder:
Do not forget to replace the suffix placeholder###
with your choosen or assigned group ID in the exercise steps below.
Make use of the classic F1 Help to get detailed information on each ABAP and EML statement in ABAP editors
The Entity Manipulation Language (EML) is an extension of the ABAP language which offers a type-safe, API-based access to RAP business objects directly by using ABAP. EML has an SQL-like syntax.
EML is used to implement the transactional behavior of RAP BOs and also access existing RAP BOs from outside the RAP context.
EML interacts with business objects by triggering their operations for specified entities. An operation can only be triggered by EML if the operation is specified for the relevant entity in the behavior definition and if it implemented accordingly.When consuming a RAP BO instance via EML, the consumer application is responsible for triggering the
COMMIT
operation afterMODIFY
statement to persist the changes temporary stored in the transactional buffer to the SAP HANA database.The EML reference documentation is provided in the ABAP Keyword Documentation. You can use the classic F1 Help to get detailed information on each statement by pressing F1 in the ABAP editors.
Further reading: EML@RAP Development Guide | EML@ABAP Keyword Documentation | ABAP for RAP Business Objects | RAP BO Contract
In this step you will create the class
ZRAP100_CL_EML_###
, where###
is your group ID, to play around with EML.
🔵 Click to expand!
-
Right-click on your package
ZRAP100_###
and choose New > ABAP Class -
Maintain the needed information (where
###
is your group ID) and choose Next > to continue:- Name:
ZRAP100_CL_EML_###
- Description:
EML Playground
- Interfaces:
if_oo_adt_classrun
For that, press Add, enter the interface name in the filter area, choose the correct entry from the list, and confirm with OK.
Assign a transport request and choose Finish to create the class.
The ABAP class skeleton is generated and displayed in the class editor.
- Name:
-
Delete the whole generated code and replace it with the one provided in the source code document linked below.
Do not forget to replace all occurences of the placeholder###
with your group ID using the Replace All function (Ctrl+F).
Source code document:
ABAP Class ZRAP100_CL_EML_###
-
Take a look at the class to understand how it works.
Brief explanation of the class definition
-
(1) Constant data for the allowed instance states
is_draft
: for draft instances (if_abap_behv=>mk-on
=01
)is_active
: for active instances (if_abap_behv=>mk-off
=00
)
-
(2) Static attributes accessible everywhere in the class
travel_id
: used to specify the ID of a travel instanceinstance_state
: used to specify the instance state (draft or active)console_output
: reference object used to write output to the Console view
-
(3) Different methods with a sample implementation of the EML-based access:
read_travel( )
: to read a travel BO entity instanceupdate_travel( )
: to update a Travel BO entity instancecreate_travel( )
: to create a Travel BO entity instancedelete_travel( )
: to delete a Travel BO entity instanceactivate_travel_draft( )
: to activate a draft Travel BO entity instancediscard_travel_draft( )
: method to discard a draft Travel BO entity instance
Brief explanation of the class implementation
-
The method
if_oo_adt_classrun~main( )
is executed when pressing F9. Its logic is quite simple: Methods are executed depending on the value set in the variableexecute
:- READ:
1
| UPDATE:2
| CREATE:3
| DELETE:4
| ACTIVATE draft:5
| DISCARD draft:6
| All Methods:55
- READ:
-
The EML statements
READ ENTITY, ENTITIES
andMODIFY ENTITY, ENTITIES
are used to implement the different operations.READ ENTITY, ENTITIES
is used to perform read-only operations on RAP BO instances.MODIFY ENTITY, ENTITIES
is used to perform transactional modify operations on RAP BO instances.
This includes standard operations (CREATE
,CREATE BY
,UPDATE
,DELETE
) - as well as standard draft operations (EDIT
,ACTIVATE
, andDISCARD
) and non-standard operations (actions) using the keywordEXECUTE
.
-
You will go through the different method implementations and try them out in the exercises below.
-
The method
read_travel( )
in classZRAP100_CL_EML_###
provides a sample implementation on how to read draft or active Travel BO entity instances.
This method is executed when the variableexecute
is set to1
or55
in the methodif_oo_adt_classrun~main( )
.
🔵 Click to expand!
-
Go to the implementation of the method
read_travel( )
and take a look at it.-
(1) The internal table
travels
- is declared using the BDEF derived type (
TYPE TABLE FOR READ IMPORT
). It is used to specify theREAD
request.
You can set the cursor on the table name and press F2 to view the element info.Read more about BDEF Derived Types
- The table for the request is filled with the information about the relevant instances.
- is declared using the BDEF derived type (
-
(2) The
READ ENTITIES
is specified and the internal tabletravels
with the relevant information.- Instead of declaring and passing an internal table, the values can be declared inline with the
VALUE
constructor. We will do so in the other methods. - Instead of the
ALL FIELDS
, a specific list of the fields to be read can be specified using the additionFIELDS ( FieldName1, FieldName2, FieldName3 )
.
- Instead of declaring and passing an internal table, the values can be declared inline with the
-
(3) Console output: Some information will be displayed in the Console view after the execution of the READ statement.
-
-
Now go to the implementation of the method
if_oo_adt_classrun~main( )
and set the variableexecute
to1
.
Also specify the ID (travel_id
) and the state (instance_state
) of the travel instance to be read.
You can get this information in your Travel Fiori elements app. -
Press F9 to run the class as console application and check the result in the Console view.
Compare the result with the value in the Travel Fiori elements app. You can also use the ABAP Debugger to investigate the response parameters. -
Repeat the test with different values (travel ID and instance state) if you like.
Further Reading: READ
The method
update_travel( )
in classZRAP100_CL_EML_###
provides a sample implementation on how to update active Travel BO entity instances. The fieldDescription
is updated.
This method is executed when the variableexecute
is set to2
or55
in the methodif_oo_adt_classrun~main( )
.The EML statement
MODIFY ENTITIES
with the standard operationUPDATE
is used in this example.
PS: You can only update your own Draft instances when using EML APIs. The standard draft operationEXECUTE Edit
must be used first when manipulating an active BO entity instance with no associated draft instance.
Info:
TheUPDATE
statement enables the editing of entity instances.Read more: MODIFY >> General Information: UPDATE
🔵 Click to expand!
-
Check the implementation of the method
update_travel( )
.
You can see that the data (i.e. internal table) for theUPDATE
request is filled inline withVALUE
operator.
Make use of the classic F1 Help to get detailed information on each ABAP and EML statement in ABAP editors. -
Now go to the implementation of the method
if_oo_adt_classrun~main( )
and set the variableexecute
to2
.
Also specify the ID (travel_id
) and the state (instance_state
) of the travel instance to be updated.
You can get this information in your Travel Fiori elements app.Check the current description in the App before executing the class.
As stated above draft instances cannot be updated with this method, but you can give it a try to see what will happen.
"specify the operation to be executed DATA(execute) = 2. ... "UPDATE a Travel BO entity instance IF execute = 2 OR execute = 55. travel_id = '0000000'. instance_state = is_active. update_travel( ). ENDIF.
-
Press F9 to run the class as console application and check the result in the Console view.
-
Check the updated description in the Travel Fiori elements app.
-
You will notice that the description has not been updated. You can execute the class again by pressing F9 in ADT.
Take a closer look at the implementation
Question: Have you find out the reason for this erroneous behavior?
Click to expand the solution!
The
COMMIT ENTITIES
statement is currently commented out. It means that the updated description is only available in the transactional buffer but not persisted in the database!To solve this issue, just comment in the
COMMIT ENTITIES
block in the source code by removing the*
at the begin of each line."persist the transactional buffer COMMIT ENTITIES RESPONSE OF ZRAP100_R_TravelTP_### FAILED DATA(failed_commit) REPORTED DATA(reported_commit).
Also comment in following lines in the console output section:
ELSEIF failed_commit IS NOT INITIAL. console_output->write( |- Cause for failed commit = { failed_commit-travel[ 1 ]-%fail-cause } | ).
Save
and activate
the changes.
Press F9 to run the class as console application and check the updated description in the Travel Fiori elements app.
-
Repeat the test with different values (travel ID and instance state) if you like.
The method
create_travel( )
in classZRAP100_CL_EML_###
provides a sample implementation on how to create new draft or active Travel BO entity instances. The actionrejectTravel
is also performed on the instance.
This method is executed when the variableexecute
is set to3
or55
in the methodif_oo_adt_classrun~main( )
.The EML statement
MODIFY ENTITIES
is used with the standard operationCREATE
and the non-standard operationEXECUTE
action
in this implementation.
Info:
TheCREATE
statement enables the creation of entity instances. TheCREATE BY
association statement uses an association of the entity specified in the EML statement in order to create instances of its child entity.
We will only use theCREATE
statement in the current exercise.
Read more: MODIFY >> General Information: CREATE and CREATE BY AssociationThe
EXECUTE Action
statement enables the execution of actions.
Read more: MODIFY >> General Information: EXECUTE Action
🔵 Click to expand!
-
Go to the implementation of the method
if_oo_adt_classrun~main( )
and set the variableexecute
to3
.
Also specify the state (instance_state
) of the new travel instance to be created. The ID will be automatically assigned by the internal early numbering."specify the operation to be executed DATA(execute) = 3. ... "CREATE a Travel BO entity instance IF execute = 3 OR execute = 55. instance_state = is_active. create_travel( ). ENDIF.
-
Press F9 to run the class as console application and check the result in the Console view.
Check the new create instance in the Travel Fiori elements app.
You can also use the ABAP Debugger to investigate the response parameters. -
Repeat the test with different instance states if you like.
The method
delete_travel( )
provides a sample implementation on how to delete active Travel BO entity instances.
This method is executed when the variableexecute
is set to4
or55
in the methodif_oo_adt_classrun~main( )
.The EML statement
MODIFY ENTITIES
with the standard operationDELETE
is used in this implementation.
PS: Draft instances cannot be deleted with this EML statement. The standard draft operationEXECUTE Discard
should be used instead.
Info:
TheDELETE
statement enables the deletion of entity instances.Read more: MODIFY >> General Information: DELETE
🔵 Click to expand!
-
Go to the implementation of the method
if_oo_adt_classrun~main( )
and set the variableexecute
to4
.
Also specify the ID (travel_id
) and the state (instance_state
) of the travel instance to be deleted.
You can get this information in your Travel Fiori elements app.As stated above draft instances cannot be deleted with this method, but you can give it a try to see what will happen.
"specify the operation to be executed DATA(execute) = 4. ... "DELETE a Travel BO entity instance IF execute = 4 OR execute = 55. travel_id = '00000000'. instance_state = is_active. delete_travel( ). ENDIF.
-
Press F9 to run the class as console application and check the result in the Console view.
Check the deleted instance in the Travel Fiori elements app.
You can also use the ABAP Debugger to investigate the response parameters. -
Repeat the test with different values (travel ID and instance state) if you like.
The method
activate_travel_draft( )
provides a sample implementation on how to activate draft Travel BO entity instances.
It is executed when the variableexecute
is set to5
or55
in the methodif_oo_adt_classrun~main( )
.The EML statement
MODIFY ENTITIES
with the standard draft operationEXECUTE Activate
is used in this implementation.
Info:
By executing the draft actionACTIVATE
on a draft instance, you copy the draft instance to active application buffer. It invokes thePREPARE
and a modify request to change the active BO instance according to the state of the draft instance. Once the active instance is successfully created or updated, the draft instance is discarded. The activate action does not save the active instance on the database. The actual save is executed separately, either byCOMMIT ENTITIES
via EML or by calling the save sequence in case of OData. In the case of OData requests, this is automatically done by the RAP framework. The activate action is only possible on draft instances.Read more: Creating Active Data
🔵 Click to expand!
-
Go to the implementation of the method
if_oo_adt_classrun~main( )
and set the variableexecute
to5
.
Also specify the ID (travel_id
) of the draft travel instance to be activated.
You can get this information in your Travel Fiori elements app. Create draft instances if needed."specify the operation to be executed DATA(execute) = 5. ... "ACTIVATE a draft Travel BO entity instance IF execute = 5 OR execute = 55. travel_id = '00000000'. activate_travel_draft( ). ENDIF.
-
Press F9 to run the class as console application and check the result in the Console view.
Check in the Travel Fiori elements app if the specified draft instances have been activated.
You can also use the ABAP Debugger to investigate the response parameters.
-
Repeat the test with different values (travel ID and instance state) if you like.
The method
discard_travel_draft( )
provides a sample implementation on how to discard draft Travel BO entity instances.
It is executed when the variableexecute
is set to6
or55
in the methodif_oo_adt_classrun~main( )
.The EML statement
MODIFY ENTITIES
with the standard draft operationEXECUTE Discard
is used in this implementation.
Info:
By executing the draft actionDISCARD
, the draft instance is deleted from the draft database table. In addition, possible exclusive locks are released. TheDISCARD
can be executed on new-drafts and on edit-drafts. Apart from releasing the lock, the action has no impact on the active instance. It is just the draft data that is deleted.Read more: Deleting Instances of a Draft BO >> Activate Action
🔵 Click to expand!
-
Go to the implementation of the method
if_oo_adt_classrun~main( )
and set the variableexecute
to6
.
Also specify the ID (travel_id
) of the draft travel instance to be discarded.
You can get this information in your Travel Fiori elements app. Create draft instances if needed."specify the operation to be executed DATA(execute) = 6. ... "DISCARD a draft Travel BO entity instance IF execute = 6 OR execute = 55. travel_id = '00000000'. discard_travel_draft( ). ENDIF.
-
Press F9 to run the class as console application and check the result in the Console view.
Check the discarded draft instance in the Travel Fiori elements app.
You can also use the ABAP Debugger to investigate the response parameters. -
Repeat the test with different draft instances if you like.
As suggested by the title: Play around with EML!
For examples,
- Copy the methods of your choice and adjust them as you like.
- Execute all operations: For that, set the variable
execute
to55
and specify the required values (travel_id
andinstance_state
) for the different operations.DATA(execute) = 55.
Feel free to ask questions.
Now that you've played around with various EML statements to
- read Travel entity instances,
- update Travel entity instances,
- create new Travel entity instances,
- delete Travel entity instances,
- activate draft Travel entity instances, and
- discard draft Travel entity instances,
you are done with this hands-on. Congratulations!
In this hands-on session, you have learned how to build a simple Fiori elements app with managed implementation type of the ABAP RESTful Application Programming Model (RAP) and how to write a BO test with ABAP Unit, and access BOs outside of the RAP context using the Entity Manipulation Language (EML)!
Thank you for attending this workshop!