On the 10th of February 2023, DJ Adams came all the way from the UK to our INNOV8iON office in De Meern to run an SAP CodeJam on service integration with the SAP Cloud Application Programming (CAP) model. CAP is a framework of tools and guidelines for developing services and applications on the SAP Business Technology Platform (BTP). One of the main advantages of CAP is that it supports various open-source programming languages such as Java and JavaScript. Moreover, CAP provides a set of pre-built services, higher-level concepts and APIs that reduce development time and avoid lock-ins to low-level features. For more information about CAP, you can take a look at the following articles: SAP CAP: What is it and what can I do with it within my organization? and SAP CAP deep-dive.
ABOUT THE CODEJAM
We started at 13:00 with a small introduction to CAP and an overview of how the rest of the day was structured. After that, we turned to our laptops to work through some exercises ourselves. At the end of each exercise, we had an in-depth discussion where DJ gave a more detailed explanation of what we just did and there was always some space for questions and remarks from the participants. After about two-third of the exercises, we had a dinner-break with some delicious Thai food and the opportunity to chat with other participants.

SETTING UP THE WORKSPACE
During the CodeJam, we went step by step through the process of creating a CAP service that consumes an external service, like an API. The first step was to set up the workspace, which could be either a Dev Space in the SAP Business Application Studio or a Dev container in Visual Studio Code. We cloned the Github repository that was made especially for this CodeJam, such that the basic “Incidents Management” service was already provided. Next to this, we manually installed the OData CSDL Modeler extension, which allows you to get graphical representation of OData definitions. The purpose of our “Incidents Management” service is to deal with incidents that are raised by customers. Those incidents are addressed in appointments and ultimately resolved by service worker personnel attending those appointments.
THE STRUCTURE OF THE CAP SERVICE
The CAP service consists of three organizational layers; the application layer, the service layer and the persistence layer. As it concerned a so-called “headless” service, the application layer was in this case as good as empty. The service layer exposes entities from the persistence layer, which contains the actual entity definitions, including some basic annotations. Both the persistence layer and the service layer can be examined graphically using the CDS Graphical Modeler from the previously installed extension.
MOCKING THE EXTERNAL SERVICE
The next step was to import an OData service definition from the SAP API Business Hub into the CAP project. We used the “Business Partner (A2X)” API from the SAP S/4HANA Cloud system, which contains data related to business partners, suppliers, and customers. From this service, we used the business partners to represent the customers who create incidents.
First, we mocked this external service. With mocking, CAP creates a simulated version of the external service, allowing developers to work on the service without the availability of an actual external service or database. It also allows you to use some test data. We started with in-process mocking and then moved it to a separate process, meaning that the external service is running on a different port. Although the latter is more representative of how cross-service communication happens in reality, the former is the simplest and fastest way to start up a CAP service with external services. So, for the sake of simplicity, we switched back to in-process mocking for a while.
In order to clean up the integration between the external service and the main service, we created two CDS definitions. In the first one, we defined a new entity – Customers – as a projection on the more generic Business Partner entity from the external service and exposed only the properties that we wanted to use. In the second CDS definition, we integrated this new entity into the main service.
Then it was time to move the mocking of the external service to a separate process again. Next, we provided a simple service implementation file in which we created a handler for handling READ requests for our new entity. In order to make calls to the remote service possible we needed to install the HTTP client library from the SAP Cloud SDK.
SETTING UP A REAL REMOTE CONNECTION TO THE EXTERNAL SERVICE
We now got to the point where we stopped mocking the external service and started to set up a real remote connection to it, in a sandbox environment (i.e. an isolated testing environment). In order to retrieve data from the remote system with a GET request, we needed to authenticate with a valid API key. A possible option for storing information on the URL and API key would be in the `package.json` file. However, this causes a big issue regarding security. Instead, we can make use of the special `.env` file, where we can store individual environment variables that can be accessed when starting up the CAP server. Since the `.env` file is a dotfile (i.e. a hidden file) it is very suitable for storing sensitive information.
At this point we could start up our CAP server again, this time using the sandbox context. Navigating to the Customers entity set we created earlier, we saw that the data is now coming from the remote system. So, when we click on the entity set, the browser sends a GET query to the CAP server, which triggers the handler for the READ event of this entity set. The handler calls a request object, which is translated into an OData query by the CAP framework. And finally, SAP Cloud SDK sends this OData query to the remote system, which returns the requested data.
ADDING AN ASSOCIATION
So far, the only relationship between the main service and the remote service was the Customers entity which is simply a projection on the Business Partner entity. So, in order to make the service more useful we had to allow incidents to be associated to a customer. As a result, the Incidents entity now also had a `customer` property, that links it to the corresponding customer. Using a file with HTTP requests, we manually created a new incident for a customer that we could use to test the functionality of the service.
WRAPPING UP
Unfortunately, we did not have enough time to finish the last exercise during the CodeJam, but using the instructions from GitHub, we had the opportunity to finish the last step in setting up our CAP service at home. This final exercise gave an introduction into how SAP Fiori elements can be extended by adding extra customization information in the CDS definitions in the form of OData annotations.

We closed the day off with some drinks for whoever wanted to have some more time to chat with other participants and exchange thoughts on the topic. Since I started working at INNOV8iON – and with SAP software in general – only two months ago, I had no experience with CAP prior to the event. This made it quite challenging to understand the theory behind service integration with CAP right away. However, the interactive nature of the CodeJam helped a lot to make the theory more tangible. Furthermore, the enthusiasm with which DJ Adams talked about the topic made it even more interesting. All in all it was a very fun and informative session and we are already looking forward to the next CodeJam. If you want to know more, you can also take a look at DJ Adams’ blog about the event.
For more CodeJam events, visit this page.