CDS is the heart of CAP
Everything in CAP starts with the Core Data Services model. Get entities, associations, and compositions right, and services, UIs, and authorization mostly fall into place. Get them wrong, and you'll fight the framework all the way.
Rule of thumb: associations link independent things; compositions own dependent things.
Entities: the basics
using { cuid, managed } from '@sap/cds/common';
entity Books : cuid, managed {
title : String(200);
price : Decimal(9,2);
stock : Integer;
}
Aspects like cuid (UUID key) and managed (createdAt, createdBy, modifiedAt, modifiedBy) keep models DRY. Define once, reuse everywhere.
Associations: relationships between independent entities
entity Books {
key ID : Integer;
title : String;
author : Association to Authors;
}
entity Authors {
key ID : Integer;
name : String;
books : Association to many Books
on books.author = $self;
}
An author exists with or without books — that's an association. The on condition defines the backlink; $self refers to the current author. CAP turns these into OData navigation properties.
Compositions: owned children
entity Orders : cuid {
items : Composition of many OrderItems
on items.parent = $self;
}
entity OrderItems : cuid {
parent : Association to Orders;
book : Association to Books;
quantity : Integer;
}
Order items belong to exactly one order — delete the order, and the items go with it. That's a composition. In Fiori Elements, compositions render as object-page sections automatically.
If the child can't meaningfully exist without the parent, it's a composition. If it can, it's an association.
Common modeling mistakes
- Missing
onconditions — unmanaged associations need explicit join conditions; CAP can't guess them. - Composition without backlink — the child needs the
parentassociation for theonclause to work. - Keys on everything by hand — use
cuidorUUIDaspects instead of inventing key strategies per entity. - Deep nesting — more than two composition levels gets hard to manage in UIs; flatten where you can.
Organizing models with namespaces
Real projects outgrow a single schema file. Use contexts and namespaces to organize:
namespace my.bookshop;
context Sales {
entity Orders : cuid { ... };
}
context MasterData {
entity Customers : cuid { ... };
}
Reference across contexts with the full path — my.bookshop.Sales.Orders. Split large domains into multiple .cds files under db/; CAP compiles them together. One file per bounded context keeps merge conflicts rare and reviews focused.
Model first, code later
A well-shaped CDS model generates database tables, OData endpoints, draft handling, and Fiori UIs. Time spent modeling is the highest-leverage time in a CAP project.
Confused by an association vs composition choice in your model? Describe it in the comments.