Search

Implementing Services

By default, a CAP application serves OData CRUD requests based on the CDS models that your application provides. This section describes how to add custom business logic for your services.

Registering Event Handlers

You can register event handlers for events on CDS services. Event handlers enable adding custom business logic to your application. A common use case is to react when data is created, read, updated, or deleted.

Event Handler Classes

First, define a class that implements the interface EventHandler and use the annotation @ServiceName to specify the fully qualified name of the corresponding service definition in the CDS model:

import com.sap.cds.services.handler.EventHandler;
import com.sap.cds.services.handler.annotations.ServiceName;

@ServiceName("my.catalogservice")
public class CatalogServiceHandler implements EventHandler {
     [...]
}

Hence, by default the event handler methods added to this class map to the CDS service my.catalogservice.

Event Handler Methods

To register for a particular event on the service, annotate a so called event handler method within an event handler class. Specify the phase, the event type and the CDS entity on which the handler should react. For example:

@After(event = "READ", entity = "my.catalogservice.books")
public void readBooksVerify(CdsReadEventContext event) {
    [...]
}

In this example, the event handler method readBooksVerify gets called after reading the data for the entity my.catalogservice.books of the service my.catalogservice.

In general, the syntax of the annotation is

@<EVENT PHASE>(event = <EVENT TYPE>, entity = <CDS MODEL ENTITY>)

Event Phases

Processing an event is separated into three phases that are executed consecutively: Before, On and After. To specify the phase in which an event handler is called use the following annotations:

@Before

When annotated with @Before, an event handler gets called during the Before phase of an event (that means, before the On and After phases are executed). The Before phase is useful for filtering, validation, and other types of preprocessing of the input parameters of an event. There can be an arbitrary number of @Before handlers per event. The Before phase is completed when one of the following conditions applies:

@On

The On phase is started after completing the Before phase without exceptions. It’s meant to implement the core processing of the event. Its handler annotated with @On computes the output parameters based on the input parameters of the event. The On phase is completed when one of the following conditions applies:

@After

The After phase is useful for post-processing of the output parameters of an event and gets executed after the On phase is completed without exceptions. Handlers are executed in this phase when annotated with @After. A handler in this phase can still abort the event processing:

Event Types

A service can receive any type of event. By default, all CDS services support the following events:

Depending on the protocol adapter API calls are mapped to event types (for example, by mapping HTTP methods). Nevertheless, arbitrary events can be sent to the service.

Calling Other Services

Frequently, the business logic implemented by the event handler requires to consume other services:

In CAP, calling a service is considered equivalent to emitting an event to the target service. The APIs for service consumption are explained in consuming services.

Introspecting the CDS Model

CAP offers a Model Reflection API to introspect the CdsModel of a CAP application and retrieve details on the services, types, entities, and their elements of the model.

Accessing the CDS Model

The model is either obtained from the EventContext or by dependency injection.

From the EventContext

The CDS model of the CAP application is available in every event handler method as it can be obtained from the getModel method:

import com.sap.cds.reflect.CdsModel;
import com.sap.cds.services.EventContext;
import com.sap.cds.services.handler.EventHandler;

@On(event = "READ", entity = "my.catalogservice.books")
public void readBooksVerify(EventContext context) {
    CdsModel model = context.getModel();
   [...]
}

By Dependency Injection in Spring

In Spring, the CDS Model is registered as a Spring Bean, which makes the model available using dependency injection:

import com.sap.cds.reflect.CdsModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyBean {
    @Autowired
    CdsModel model;
}