CDS Views
Architect / Cross-trackintermediate

CDS Views Part 5: VDM Layering — Basic, Composite and Consumption Views

Key takeaway

Understand the Virtual Data Model (VDM) layers used in S/4HANA: basic interface views over single tables, composite views that combine them, and consumption views built for one app or report. Learn naming, the @VDM annotations and how to reuse SAP's released I views.

Explanation

📌 KEY POINTS
✅ VDM = Virtual Data Model: S/4HANA's layered CDS architecture — basic (I_), composite (I_) and consumption (C_) views.

✅ Basic views sit on one table, give business names and stay free of app logic; composite views combine basic views; consumption views are shaped for one app, report or API.

✅ @VDM.viewType: #BASIC / #COMPOSITE / #CONSUMPTION documents the layer.

⚠️ Build on SAP's released I_ views where possible (C1 release contract) — they stay stable across upgrades; direct table access and unreleased views may break.

━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE

Parts 1–4 built single views. Real projects need an architecture of views that can be reused and maintained.

━━━━━━━━━━━━━━━━━━━━
▶ 1. BASIC (INTERFACE) VIEWS

  • One main data source (usually one table), no heavy logic.
  • Business aliases, key definition, currency/unit references, associations to related basic views.
  • Examples from SAP: I_Customer, I_SalesOrder, I_Product.
  • Customer naming: ZI_<BusinessObject>.

━━━━━━━━━━━━━━━━━━━━
▶ 2. COMPOSITE VIEWS

  • Combine basic views via associations or joins; may add calculations and aggregations.
  • Still reusable — not tied to one app.
  • Example: sales order with customer name and open value.

━━━━━━━━━━━━━━━━━━━━
▶ 3. CONSUMPTION VIEWS

  • Built for one purpose: a Fiori app, an OData service, an analytical query or a report.
  • Contain UI, search and analytical annotations (Part 7), selection of only needed fields, sometimes parameters.
  • Naming: ZC_<Purpose>. Consumers should only read consumption or released interface views.

━━━━━━━━━━━━━━━━━━━━
▶ 4. RELEASED VIEWS AND STABILITY

  • SAP marks some views as released (API state "Released" in ADT, C1 contract for use in key user / cloud development).
  • In S/4HANA Cloud and ABAP Cloud, only released objects may be used.
  • On-premise you technically can read any view or table, but released views survive upgrades.

━━━━━━━━━━━━━━━━━━━━
▶ 5. WHY LAYERING PAYS OFF

  • Logic defined once in the lower layer; many consumers reuse it.
  • Changes are made in one place.
  • Clear boundary between reusable model and app-specific shape.

━━━━━━━━━━━━━━━━━━━━
▶ 6. ANTI-PATTERNS

  • One giant view per report with 15 joins.
  • Consumption views reading other consumption views.
  • Copying SAP views instead of extending them.

━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP

  1. Search SAP's views in ADT (Ctrl+Shift+A, "I_Customer"), check the API state.
  2. Build ZI_Customer (basic) over KNA1.
  3. Build ZI_SalesOrderComp (composite) over VBAK with an association to ZI_Customer.
  4. Build ZC_SalesOrderOverview (consumption) exposing only the fields one report needs.
  5. Read ZC_SalesOrderOverview from a classic report.

✅ CHECKPOINT: you can place any new CDS view in the correct VDM layer and name it accordingly.

Code example

ABAP Code
// ===== STEP 1: basic view - one table, business names =====@AccessControl.authorizationCheck: #NOT_REQUIRED@EndUserText.label: 'Customer - basic'@VDM.viewType: #BASICdefine view entity ZI_Customer  as select from kna1{  key kunnr as Customer,      name1 as CustomerName,      land1 as Country,      ort01 as CityName} // ===== STEP 2: composite view - combines basic views =====@AccessControl.authorizationCheck: #NOT_REQUIRED@EndUserText.label: 'Sales order - composite'@VDM.viewType: #COMPOSITEdefine view entity ZI_SalesOrderComp  as select from ZI_SalesOrderHeader  association [1..1] to ZI_Customer as _Customer    on $projection.SoldToParty = _Customer.Customer{  key SalesOrder,      CreationDate,      SalesOrganization,      SoldToParty,      @Semantics.amount.currencyCode: 'TransactionCurrency'      NetAmount,      TransactionCurrency,      _Customer} // ===== STEP 3: consumption view - shaped for one report =====@AccessControl.authorizationCheck: #NOT_REQUIRED@EndUserText.label: 'Sales order overview - consumption'@VDM.viewType: #CONSUMPTIONdefine view entity ZC_SalesOrderOverview  as select from ZI_SalesOrderComp{  key SalesOrder,      CreationDate,      SoldToParty,      _Customer.CustomerName as CustomerName,      _Customer.Country      as Country,      @Semantics.amount.currencyCode: 'TransactionCurrency'      NetAmount,      TransactionCurrency} * ===== STEP 4: classic report reads only the consumption view =====REPORT zcds_so_overview. TYPES: BEGIN OF ty_ov,         salesorder   TYPE vbeln_va,         customername TYPE name1_gp,         country      TYPE land1_gp,         netamount    TYPE netwr_ak,         transactioncurrency TYPE waerk,       END OF ty_ov. DATA: lt_ov TYPE STANDARD TABLE OF ty_ov,      ls_ov TYPE ty_ov. PARAMETERS p_land TYPE land1_gp DEFAULT 'DE'. START-OF-SELECTION.  SELECT salesorder customername country netamount transactioncurrency    FROM zc_salesorderoverview    INTO TABLE lt_ov    WHERE country = p_land.   LOOP AT lt_ov INTO ls_ov.    WRITE: / ls_ov-salesorder, ls_ov-customername,             ls_ov-netamount CURRENCY ls_ov-transactioncurrency.  ENDLOOP.

Real project scenario

On a global S/4 rollout, each market team wrote its own sales views directly on VBAK/VBAP/KNA1. After two years there were 60 overlapping views, and a change in how "open value" was calculated had to be applied in 14 places.
The architecture team introduced a VDM rule: ZI_ basic views per business object, shared composite views for common logic, ZC_ consumption views per app. Where SAP already offered a released I_ view (I_Customer, I_SalesOrder) they built on it. New reports reused the composite layer, and the next logic change touched one view.

Common mistakes

  • Putting app-specific UI annotations and filters into basic views.
  • Consumption views selecting from other consumption views.
  • Rebuilding a view SAP already delivers as released I_ view.
  • Reading raw tables in consumption views instead of basic views.
  • Missing @VDM.viewType, so nobody knows the intended layer.

Best practices

  • Basic → composite → consumption; consumers read only consumption or released views.
  • Prefer SAP released I_ views as the foundation.
  • Name consistently (ZI_, ZC_) and annotate @VDM.viewType.
  • Keep basic views thin and reusable.
  • Document the view stack for each app.

Interview angle

Questions: "What is the VDM?", "Difference between basic, composite and consumption views?", "What is a released CDS view?"
Strong answer: VDM is S/4HANA's layered CDS model; basic views over single tables with business names, composite views combining them for reuse, consumption views shaped for one app with UI/analytics annotations. Released views have a stability contract and are the only ones allowed in ABAP Cloud; building on them reduces upgrade risk.

Practice this lesson

Quick check

1. Which VDM layer should contain UI annotations and the field selection for one specific Fiori app?

2. In S/4HANA, why should custom CDS views preferably build on SAP's released I_ views instead of raw tables?

3. Which statement adds fields to an SAP CDS view entity without modifying its source?

Interview questions

1. What is the difference between a Basic, Composite, and Consumption CDS view?

Answer it in your own words first, then compare.

2. How would you structure a CDS model for a domain?

Answer it in your own words first, then compare.

Practice more with Interview AI →

Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.

More lessons in this topic

Interview questions on this topic

Related SAP topics