Search

    Services

    Services are one of the core concepts of CAP. This section describes how services are represented in the CAP Java SDK and how their event-based APIs can be used. One of the key APIs provided by services is the uniform query API based on CQN statements.

    Content

    An Event-Based API

    Services dispatch events to Event Handlers, which implement the behaviour of the service. A service can process synchronous as well as asynchronous events and offers a user-friendly API layer around these events.

    Every service implements the Service interface, which offers generic event processing capabilities through its emit(EventContext) method. The Event Context contains information about the event and its parameters. The emit method takes care of dispatching an Event Context to all event handlers registered on the respective event and is the central API to process asynchronous and synchronous events.

    Most services implement an interface, which extends the Service interface. These interfaces provide a more user-friendly API layer around the emit method, based on the events and capabilities provided by the service. Examples for these services are, the Application Service, Persistence Service, and Remote Service, which offer a common CQN query execution API for their CRUD events. However, also technical components are implemented as services, for example the AuthorizationService or the MessagingService.

    Using Services

    Often times your Java code needs to interact with other services. The ServiceCatalog provides programmatic access to all available services. The Service Catalog can be accessed from the Event Context or from the CdsRuntime.

    ServiceCatalog catalog = context.getServiceCatalog();
    Stream<Service> allServices = catalog.getServices();
    Stream<ApplicationService> appServices = catalog.getServices(ApplicationService.class);
    

    To look up a service in the Service Catalog, you need to know its name. Application Services are created with the fully qualified name of their CDS definition by default:

    ApplicationService adminService = catalog.getService(ApplicationService.class, "AdminService");
    

    Technical services, like the Persistence Service have a DEFAULT_NAME constant defined in their interface:

    PersistenceService db = catalog.getService(PersistenceService.class, PersistenceService.DEFAULT_NAME);
    

    When running in Spring, all services are available as Spring beans. Dependency injection can therefore be used to get access to the service objects:

    @Component
    public class EventHandlerClass implements EventHandler {
    
        @Autowired
        private PersistenceService db;
    
        @Autowired
        @Qualifier("AdminService")
        private ApplicationService adminService;
    
    }
    

    Triggering Custom Events

    Services can be extended with custom events, for example through Actions and Functions. In that case, the custom event can be triggered by passing the corresponding Event Context to the emit method of the service. In case of model-defined actions and functions, the CDS Maven Plugin is capable of generating Event Context interfaces. Alternatively developers can always define their own custom event contexts.

    In addition developers can define their own API layer around the emit method, to make it more convenient to trigger the custom event. The following example shows how this can be achieved for the action example from the Application Services chapter in a Spring Boot application.

    import static bookshop.Bookshop_.BOOKS;
    
    @Component
    public class CatalogServiceAPI {
    
        @Autowired
        @Qualifier(CatalogService_.CDS_NAME)
        CqnService catalogService; // get access to the service
    
        public Reviews review(String bookId, Integer stars) {
            ReviewEventContext context = ReviewEventContext.create();
            context.setCqn(Select.from(BOOKS).byId(bookId)); // set target entity
            context.setStars(stars); // set input parameters
            catalogService.emit(context); // emit the event
            return context.getResult(); // return the result
        }
    
    }
    

    Services Accepting CQN Queries

    The most used services in CAP are the CQN-based services. The most prominent of these are the Application Service, Persistence Service, and Remote Service. Those services can handle CRUD events by accepting CQN statements. They all implement the common interface CqnService, which defines the CQN-based APIs.

    To learn more about how to run queries on these services, see sections Building CQN Queries and Executing CQN Queries.

    Application Services

    Application Services define the APIs that are exposed by a CAP application to its clients. They’re backed by a CDS Service definition in the CDS model, which defines the structure of the API. Consequently, they only accept CQN statements targeting entities that are defined as part of their service definition. Typically these services are served by protocol adapters, such as OData V4, which use their CQN-based APIs.

    Learn more about adding business logic to Application Services.

    Application Services are automatically augmented with generic providers (built-in event handlers), which handle common aspects such as authorization, input validation, implicit pagination and many more. Their default ON event handler delegates CQN statements to the Persistence Service.

    Learn more about these capabilities in our Cookbooks.

    The creation of Application Services can be customized through configuration. By default an Application Service is created for every service that is defined in the CDS model. Through configuration, it’s also possible to create multiple Application Services based on the same model definition.

    Learn more about the configuration possibilities in our CDS Properties Reference.

    Draft Services

    If an Application Service is created based on a service definition, that contains a draft-enabled entity, it also implements the DraftService interface. This interface provides an API layer around the draft-specific events, and allows to create new draft entities, patch, cancel or save them, and put active entities back into edit mode. Learn more about Draft Services in section Fiori Drafts.{:.learn-more}

    Persistence Services

    Persistence Services are CQN-based database clients. CAP applications most commonly use SQL databases like SAP HANA in production. For test and development, it’s also possible to use a light-weight, in-memory database such as SQLite. The CAP Java SDK therefore provides a JDBC-based Persistence Service implementation out-of-the-box. However, also other Persistence Service implementations based on NoSQL databases, such as MongoDB, are possible, even if not provided by the CAP Java SDK ready to use.

    Learn more about supported databases and their restrictions.

    A Persistence Service isn’t bound to a specific service definition in the CDS model. It’s capable of accepting CQN statements targeting any entity or view that is stored in the corresponding database.

    Transaction management is built in to Persistence Services. They take care of lazily initializing and maintaining database transactions as part of the active changeset context.

    Some generic providers are registered on Persistence Services instead of on Application Services, like the ones for managed data. This ensures that the functionality is also triggered, when directly interacting with a Persistence Service.

    The Persistence Service is used when implementing event handlers for Application Services, for example when additional data needs to be read when performing custom validations. Additionally, the default ON event handler of Application Services delegates CQN statements to the Persistence Service.

    Remote Services

    Remote Services are CQN-based clients for remote APIs, for example OData. They’re backed by a CDS Service definition, that reflects the structure of the remote API. The CDS service definition is usually imported, for example from an EDMX specification.

    They can be used when integrating APIs provided by the application with APIs provided by other applications or micro-services. This integration can happen synchronously by delegating CQN statements from Application Services to Remote Services or asynchronously by using Remote Services to replicate data into the applications own persistence.

    Remote Services need to be explicitly configured and are never created automatically. The configuration of a Remote Service specifies the destination where the remote API is available and its protocol type. It’s also possible to create multiple Remote Services with different destinations based on the same model definition. If a Remote Service is created for a service definition in the CDS model, no Application Service is automatically created for that definition.

    Learn more about how to configure and use Remote Services.

    Show/Hide Beta Features