Prerequisites
To follow-up with this blog post you must have read and completed the following previous blog posts in this series:
Create the Service Definition File
In the last blog post from this series, we have defined the data model for our solution and populated it with some initial test data. But, when we first run the application we noticed no services have been defined, thus the entities where not exposed.
In this section we will create such service definition.
1. On the left-hand pane of SAP Business Application Studio, select the srv folder, then click on the three dots to the right of the project name and select New File

Figure 1 - Create New File
2. On the dialog name the file projman-service.cds and click OK

Figure 2 - Set File Name
Service Definition Coding
Copy and paste the
code snippet below into the recently created file:
using sfsf.projman.model.db as model from '../db/projman-model';
using PLTUserManagement as UM_API from '../srv/external/PLTUserManagement.csn';
namespace sfsf.projman.service;
service ProjectManager @(path : '/projman') {
@odata.draft.enabled
entity Project as projection on model.Project;
entity Member as
select from model.Member {
* ,
member.defaultFullName as member_name
};
entity Activity as projection on model.Activity;
@readonly
entity SFSF_User as
select from UM_API.User {
key userId,
username,
defaultFullName,
email,
division,
department,
title
};
annotate SFSF_User with @(cds.odata.valuelist);
}
Let's quickly analyze the service definition code:
First we import the
solution model from the file we created in the previous blog post as well as the
PLTUserManagement OData service we imported in the third blog post referencing them through the aliases:
model and
UM_API, respectively
Then we define a
namespace to contain the service definition (sfsf.projman.service) and through which we will refer to it in the future.
Next, we declare (define) a service named
ProjectManager to be hosted at the path "
/projman", so it will be invoked through the syntax
<application host>/projman/<entity name> (or
$metadata to fetch the service metadata).
Finally, into the service, we
project the entities from our model (only those which are
not annotated with @CDS.autoexpose) and the
SFSF_User selecting some
specific fields from the
SuccessFactors User entity.
In the
Member entity, besides all regular fields, we add an
additional projection of an attribute coming from the association to the
Employee entity (defaultFullName) as
member_name, which will be further used in some
UI annotations.
We also annotate the Project entity (the root entity of our model) with
@odata.draft.enabled, because CAP exposes services via the
OData v4 protocol and, for that version,
Fiori Elements only displays the
CRUD actions in the UI if the entity is
draft-enabled. The
SFSF_User entity is annotated as
@readonly and with
@CDS.odata.valuelist as it will be used to populate the value help with SuccessFactors Users to be picked as employees assigned to projects.
Check Service
Now that we have properly defined a service and exposed the desired entities, you should notice that, in the Terminal, cds watch has updated:

Figure 3 - Serving the CAP Service
It's now serving the
ProjecManager service at path
/projman reading from the service definition file we just created. So, if you go back to the
application preview tab (the one that has opened when you CTRL-clicked
http://localhost:4004) and do a
refresh, you should now see links to
all exposed entities as well as to the
service metadata:

Figure 4 - Service Endpoints
You can click on
any entity link (
except the
SFSF_User) to view the data that has been loaded from the CSV files. Let's click, for example, on the
Project entity:

Figure 5 - Project data from service call
Notice that CAP has automatically added the
draft control attributes due to the
@odata.draft.enabled annotation.
If you click the
SFSF_User link you'll get an error, because that's not an entity defined in the application data model but rather a projection of an entity which should be populated via an OData service consumption. Therefore, CAP cannot use its generic service handlers for such entity as the OData call is delegated to the logic defined by the developer. Thus, for that kind of entities, a custom handler (with specific business logic) must be implemented and we'll do it in the next blog post from this series.
Conclusion
Congratulations! You have successfully created and tested the CAP service of the application. In the next blog post, we will add the business logic of the application following the business rules defined in the series introduction and preparation.
NOTE: all the
instructions provided in this blog post
apply exactly the same to
any CAP project that extends
other applications (SAP S/4HANA Cloud, SAP Ariba, SAP CX, and other third-party), if you would like to try it in the future.
Please, do not hesitate to
submit your questions in
SAP Community through the
Q&A tag link:
https://answers.sap.com/index.html
Next blog post in this series