Usage Scenario
Your company is planning to build an extension application using the SAP Cloud Application Programming Model (CAP). The generic service handlers that the framework provides for standard CRUD operations (CREATE
, READ
, UPDATE
, DELETE
) do not fully satisfy the application's requirements. You want to implement custom business logic on top of the standard functionality. For that, you need to understand the concept of event handlers in CAP.
Event Handlers in CAP
An Example
Think of a simple application, that manages your company's IT inventory. For each asset category, there is an entity, for example Notebooks
, Phones
, Tablets
. The entities are exposed via an inventory
service. The service provides an OData API that enables you to interact with the entities. Let's say you want to see the current inventory of notebooks. You perform a GET
request to the inventory/Notebooks
service. Within CAP, a READ
event is triggered for the Notebooks
entity. There is a built-in event handler (also known as Generic Provider) that retrieves the requested data from the database on
a READ
event for the Notebooks
entity.
Making use of Event Handlers
CAP handles all CRUD events (CREATE
, READ
, UPDATE
, DELETE
) out-of-the-box. You do not need to take any further steps after defining your entities and services. But often times, the standard functionality does not fulfill all of your requirements. You want to implement custom logic. In these cases, you can make use of the handler registration API of the CAP Service SDK for Node.js.
Extending the Example Above
Let's assume you are building a UI on top of your inventory service. It should display when a device is eligible for replacement. Whether a device is eligible for replacement depends on device type, date of acquisition, or country - thus there is no easy answer. Your service needs to uncover it. Within your entities there is a boolean field eligible_for_replacement
, which is set to false
by default.
Whenever there is a READ
event for any of the entities in your inventory
service, after
the entities have been read, you want to have a custom event handler finding out, whether the individual devices are eligible for replacement or not. It could look like the following:
cds.serve('inventory-service') .with (function(){
this.after('READ', '*', (devices)=>{
for (let each of devices) {
var deviceAge = calculateDeviceAgeYears(each)
if (deviceAge >= 4) {
each.eligible_for_replacement = true
} else {
each.eligible_for_replacement = false
}
}
})
})
The code defines that after
each READ
of any (*) entity in your inventory
service, the eligibility for replacement should be calculated. The method loops through each line of the data that was fetched by the generic service handler. Note that instead of registering the handler method for any entity (*), you could also register the event handler for a specific entity, for example Notebooks
.
In this simple example, eligibility for replacement only depends on the age of the device, but you can grasp that almost anything is possible here.
Event Phases
Events are processed in three phases that are executed consecutively: Before
, On
, and After
. When registering an event handler, the phase in which the event handler should be called, needs to be specified. In the previous example the handler method was specified for the After
phase. It is possible to register multiple event handlers for each event phase.
Summary
You can now explain the concept of event handlers in CAP.
Also, you are able to evaluate whether a custom event handler is required, and you are able to perform basic implementation of custom event handlers.