As you saw at the end of the previous exercise, there's a basic "Incidents Management" service that's supplied. This will be the starter for your explorations. Think of it as your "local" service. It's in the incidents/ directory. At the end of this exercise, you'll feel comfortable with what that service offers, and have explored its components.
All activities in this and subsequent exercises, unless otherwise stated, will be in the context of this
incidents/
directory (which you are already likely to be in, in your current terminal session, following the end of the previous exercise).
The service deals with incidents that are raised and discussed, and that are ultimately resolved by service worker personnel attending appointments to address and repair whatever is needed.
As a classic CAP based service, the core components are to be found within the lower two of the three normal organizational layers, which are presented here in an order that represents how one would normally view the layers of an application in general:
Organizational Layer | Directory | Content |
---|---|---|
Persistence | db/ |
The actual entity definitions complete with element details, relationships, supporting artifacts such as enumerations, and even some basic annotations, defined in schema.cds (there are CSV files providing some sample data for each entity at this layer too). |
Service | srv/ |
The single service, defined in incidents-service.cds, exposing entities from the persistence layer below, in a lightweight and fairly "transparent" way. |
Application | app/ |
Very little, as this is a "headless" service, although some annotations are provided at this layer (in fiori.cds) to augment the SAP Fiori elements frontend pages which CAP provides out of the box. |
👉 Take a few moments to look through these directories and become familiar with their contents.
While it's important to feel comfortable reading and writing declaratively in CDS's definition language CDL, it also doesn't hurt to use an editor extension to view the same information graphically sometimes too.
See the link in Further reading below for more information on CDL.
👉 In your workspace, find the db/schema.cds
file and use the context menu item "Open With...", selecting the "CDS Graphical Modeler" item in the selection presented to you:
You will be presented with a graphical model representing the details in db/schema.cds
, looking something like this:
You may have to use this button to reveal the property sheet on the right:
👉 Take a few moments to stare at this to see what reveals itself. Here are few pointers to what's available here:
-
on the right hand side various components and properties are listed, including imports, entities and so on
-
in the main graphical display there are entities, such as
Incidents
andServiceWorkers
(note the icon denoting entities) -
there are relationships shown between the entities, such as the one-to-many relationship between
ServiceWorkers
andAppointments
-
the enumerations (enums) are used to provide possible values for certain elements (such as for
urgency
andstatus
) -
the main namespace is
acme.incmgt
but there are also namespaces from the imported items (via the CDSusing
statement at the beginning ofdb/schema.cds
)
👉 Try to relate what you have discovered in this graphical display to the definitions in the db/schema.cds
file.
Now it's time to move up a layer, from persistence to service.
👉 Find the srv/incidents.cds
file, and open it with the CDS Graphical Modeler. Like before, take a few moments to stare at the graphical representation of the service layer; here are some pointers to what you should notice:
- this time the main namespace is
IncidentsService
and there are imported namespaces too - in contrast to the entities shown in the graphical display of
db/schema.cds
we now see projections (note the icon is different from the one that represented entities previously) - there isn't a one-to-one mapping of projections to all entities
- but where there is a mapping, there's a one-to-one element correlation (i.e. all the elements at the persistence layer are available at this service layer)
Now you feel more familiar with the baseline service for this CodeJam, why not start it up?
👉 Make sure you're in the incidents/
directory and start things up like this:
cds watch
👉 Observe how the service starts up, and examine the messages emitted. They should be similar to this:
cds serve all --with-mocks --in-memory?
live reload enabled for browsers
___________________________
[cds] - loaded model from 4 file(s):
app/fiori.cds
srv/incidents-service.cds
db/schema.cds
node_modules/@sap/cds/common.cds
[cds] - connect using bindings from: { registry: '~/.cds-services.json' }
[cds] - connect to db > sqlite { url: ':memory:' }
> init from db/data/acme.incmgt-TeamCalendar.csv
> init from db/data/acme.incmgt-ServiceWorkers.csv
> init from db/data/acme.incmgt-Incidents_urgency.texts.csv
> init from db/data/acme.incmgt-Incidents_urgency.csv
> init from db/data/acme.incmgt-Incidents_status.texts.csv
> init from db/data/acme.incmgt-Incidents_status.csv
> init from db/data/acme.incmgt-Incidents.csv
> init from db/data/acme.incmgt-Incidents.conversation.csv
> init from db/data/acme.incmgt-Appointments.csv
/> successfully deployed to in-memory database.
[cds] - using auth strategy { kind: 'mocked', impl: 'node_modules/@sap/cds/lib/auth/basic-auth' }
[cds] - serving IncidentsService { path: '/odata/v4/incidents', impl: 'srv/incidents-service.js' }
[cds] - server listening on { url: 'http://localhost:4004' }
[cds] - launched at 1/28/2024, 1:26:46 PM, version: 7.5.3, in: 925.666ms
[cds] - [ terminate with ^C ]
Unless you've turned this type of notification off in your workspace settings, you should see a message appear in your workspace to the effect that port 4004 is open and available; here's an example from VS Code:
Here's the equivalent message from a Dev Space in the SAP Business Application Studio:
👉 Open http://localhost:4004 in your browser, and examine the resources available. You should see something similar to this:
While this is not unexpected, take a moment to consider what else is evident from the content of this generated web page, beyond the list of entities with links to the corresponding entity set resources and Fiori preview apps:
- There are no "Web Applications" as this is a headless service (and we have very little in the Application layer, certainly not any HTML)
- There are endpoints for just a single service, and that service is represented by the service path
/odata/v4/incidents
, which just happens also to be the path to the corresponding OData service document (at http://localhost:4004/odata/v4/incidents), just as/odata/v4/incidents/$metadata
happens to be the path to the metadata document of the service (at http://localhost:4004/odata/v4/incidents/$metadata)
If you're wondering about the
/odata/v4
protocol prefix of the service path/odata/v4/incidents
, this was added in the June 2023 release.
At this point you've examined and started up the base CAP service that you'll be working with and extending in this CodeJam. If you were to sketch a simple entity relationship diagram it would look something like this:
┌────────────────┐ ┌────────────────┐
│ │* 1│ │
│ Conversations ├───────┤ Incidents │
│ │ │ │
└────────────────┘ └───────┬────────┘
│
│
1│
┌───────┴────────┐
│ │
│ Appointments │
│ │
└───────┬────────┘
*│
│
1│
┌───────┴────────┐
│ │
│ ServiceWorkers │
│ │
└────────────────┘
- CDS Definition Language (CDL)
- Domain Modeling with CDS
- An introduction to CDS Graphical Modeler for SAP Business Application Studio
If you finish earlier than your fellow participants, you might like to ponder these questions. There isn't always a single correct answer and there are no prizes - they're just to give you something else to think about.
-
In looking at the graphical display of the
srv/incidents-service.cds
contents, one of the entities (from thedb/schema.cds
layer) wasn't shown. Which one, and why? -
There's a lot to unpack from the initial output of
cds watch
. What does the output tell you? -
cds watch
is actually just a shortcut for anothercds
command. What is it? -
With the June 2023 release, default service paths gained a 'protocol prefix'. This means that the service path is prefixed with
/odata/v4
, to become/odata/v4/incidents
. Prior to the June 2023 release, the service path would have been simply/incidents
. If we preferred the service to be served at this simpler path, how could we specify that?