Explaining Event Handling in CAP

After completing this lesson, you will be able to:

After completing this lesson, you will be able to:

  • Evaluate when to use event handlers

Event Handling - CAP Service SDK for Node.js

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.

Introducing Registering Event Handlers

Option 1
In this method, the Javascript file is placed next to the CDS (.cds) file used to define the service, the Javascript file needs to have the same name as the .cds file, this way the framework hooks up the implementation to the service file.
Option 2
Here we set the link through the impl annotation in your CDS model file (.cds), where the respective service implementation can be found. This is useful if you have diverging file names or you want to make it very explicit that the two files belong together.
Option 3 and 4
These are fairly advanced, and used with the CDS serve API to bootstrap your services on your own.
Option 5
This is used when dealing with external services.

Request Objects

Request objects are passed in the event handlers, they provides all sorts of information about the context, like the request data or the method, like get post and so on. Request objects are also used to provide error messages back to the client, or to register another set of handlers for the request lifecycle, like when the request has completed, succeeded, or failed.

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 using 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. However, 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:

Code snippet

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. Likewise, a single handler can handle multiple events.

In the case of an external service, there wouldn't be anything that the framework could do, so you must provide an 'on' handler, but you can also use the 'on' hook to override generic CRUD handlers. However, it is recommended to use a generic implementation and only diverge from it if you need different logic.


You can now explain the concept of event handlers in CAP.

Additionally, you are able to evaluate whether a custom event handler is required, and you are able to perform basic implementation of custom event handlers.

Further Reading

For more information, consult the following:

Log in to track your progress & complete quizzes