Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
Showing results for 
Search instead for 
Did you mean: 
Active Participant
part 1 the story begins

part 2 reuse, localization, annotations

part 3 part 3 build a UI and deploy to Cloud Foundry

part 4 deploy to cloud foundry as multi-target app


Once I finished part 1 of the series, I thought that if I want to build a bigger and more complex application with SAP Cloud Application Programming Model, maybe I should take reference of the itelo, product catalog and foundation and reorganize the project code a bit to make it more reusable and less messy before I heading up towards the UI part.

One more thing, we will have a look at how to use the "CodeList" from @Sap/cds/common package.

The Plan

I am going to do some restructure of the project files, accrording to the cap development best practices, then experiment a bit on localization. Lastly I will put some annotations to make the preview screen of the matches and teams more beautiful.


1. Remember to do an npm update and npm install to bring down the latest cds version and other dependencies.
>cds -v
@sap/cds: 3.18.1
@sap/cds-compiler: 1.19.2
@sap/cds-messaging: 1.2.1
@sap/cds-ql: 1.19.2
@sap/cds-reflect: 2.8.0
@sap/cds-rest: 1.2.0
@sap/cds-services: 1.19.1
@sap/generator-cds: 2.9.0

Get Started

Change on the data model

1. Here is the new db/data-model.cds. I have created a new "type" called "Team", then I can reuse the type for both "homeTeam" and "awayTeam". "Teams" entity is reusing the "CodeList" provided by @Sap/cds/common package.
namespace com.epl;

using { managed, cuid, sap.common.CodeList } from '@sap/cds/common';

type Team : Association to Teams;

entity Teams : managed, CodeList {
key ID : Integer @(title : '{i18n>homeTeam}');

entity Matches: cuid, managed {
matchDate: Date;
homeTeam : Team;
awayTeam: Team;
homeTeamScore: Integer;
awayTeamScore: Integer;

No Change on the service catalog

namespace com.epl;

using com.epl as db from '../db/data-model';

service CatalogService {
entity Teams as projection on db.Teams;
entity Matches as select from db.Matches
order by matchDate desc;

Index.cds file

1. Best practice guide mentioned an index.cds on the project root is recommended to modularize cds projects. I created a new index.cds file like this
namespace com.epl;

using from './db/data-model';

using from './srv/cat-service';

using from './srv/Matches-annotations';

using from './srv/Teams-annotations';

2. Note that there are two new annotation files included in here. They will be addressing these files later in the post. In this way, we can include multiple data model files, catalog service files (which I am planning to do in the future posts) and we can easily include/exclude different modules.

3. Make sure this entry is updated in the package.json
  "files": [


1. I like to seperate annotations based on entities. It will make the project easy to maintain once it is growing bigger.

2. Matches-annotation.cds. See we created some filters with the code list (value help) just by putting annotations.
using com.epl.CatalogService from './cat-service';

annotate CatalogService.Matches with @(
Identification: [{ Value: '{i18n>matches}' }],
SelectionFields: [ 'matchDate','homeTeam_ID','awayTeam_ID' ],
LineItem: [
{ Value: matchDate, Label: '{i18n>matchDate}' },
{ Value:, Label: '{i18n>homeTeam}' },
{ Value: homeTeamScore },
{ Value: ':' },
{ Value: awayTeamScore },
{ Value:, Label: '{i18n>awayTeam}' }
matchDate @title:'{i18n>matchDate}';
homeTeam @(
Common: {
Label: '{i18n>homeTeam}',
ValueList: {
Label: '{i18n>homeTeam}',
CollectionPath: 'Teams',
{ $Type:'Common.ValueListParameterInOut', LocalDataProperty: 'homeTeam_ID', ValueListProperty:'ID' },
{ $Type:'Common.ValueListParameterDisplayOnly', ValueListProperty:'name' },
awayTeam @(
Common: {
Label: '{i18n>awayTeam}'

3. Teams-annotations.cds is coving the annotations for the "Teams" entity. There is an annotation @CDS.odata.valuelist which can also be used to "mark" an entity type as codelist (value list, value help or whatever...), if you do not want to borrow it from the out-of-box "sap.common.codelist".
using com.epl.CatalogService from './cat-service';

annotate CatalogService.Teams with @(
UI: {
Identification : [name],
SelectionFields: [name],
LineItem: [
{ Value: ID, Label: '{i18n>ID}' },
{ Value: name, Label: '{i18n>name}' }
ID @title:'{i18n>ID}' @UI.HiddenFilter;
name @title:'{i18n>name}';

//annotate CatalogService.Teams with @cds.odata.valuelist;

A Quick Test

1. We do a quick test by
cds deploy && cds watch .

2. Teams preview

3. Matches preview

4. Choose the Home Team or Away Team filter on the top. The Code List popped up.

5. Live update on the filter. Looks pretty good.


1. create a file _i18n/ Obviously I already created _i18n/ file for English (default language).

2. Go to the url with the sap-language parameter

3. Check the results. Awesome!!!

4. What about the team names, I want to display them in Chinese too. Let's try to load some data into com.epl-Teams_text.csv.

5. Unfortunately it does not work. The cause is that cds only creates localized view on de and fr language in sqlite db. A possible bug we found?

6. To prove that I loaded the csv as de (German).

7. Check the results in

Thanks Walldorf we got it working. 🙂


Next Step

I will official dive into the UI part, as I think we have played enough with the fiori preview.

Stay tuned. #epl-app


Part2 branch in github.
1 Comment
Labels in this area