sapui5tutors SAPUI5 • Fiori • SAP BTP Step-by-step tutorials Real project examples Interview Q&A
Practical SAPUI5 • Fiori • SAP BTP tutorials and interview prep

RAP Projection Views Explained: Shaping Your OData Service

The projection is the public face of your business object

A RAP business object is built in layers. The interface view (ZI_) holds the stable data model — fields, associations, compositions. The projection view (ZC_) sits on top and decides what the outside world actually sees.

Every OData service exposes the projection, never the interface view. So if you've ever wondered where to hide an internal field or rename something for the UI, the answer is: in the projection.


Interface vs projection: who owns what

The interface view owns the truth. It defines the entity graph, the key fields, the associations between root and child. Behavior (BDEF) is defined against it. It changes rarely and carefully.

The projection view owns the presentation. It selects a subset of fields, renames them for consumers, redirects associations to the projected targets, and carries the provider contract that declares what kind of service it feeds (transactional_query for Fiori/OData, transactional_interface for API-style consumption).

One interface view can feed several projections — a full Fiori projection, a slim API projection, an analytics projection. Model once, expose many ways.


A projection view, annotated

@EndUserText.label: 'Sales Order (Projection)'
@Metadata.allowExtensions: true
define root view entity ZC_SalesOrder
  provider contract transactional_query
  as projection on ZI_SalesOrder
{
  key OrderID,
      CustomerID,
      NetAmount,
      CurrencyCode,

      /* expose the association, redirected to the projected child */
      _Items : redirected to composition child ZC_SalesOrderItem
}

Notice what's missing: no field the UI doesn't need, no internal technical columns. redirected to composition child keeps the parent-child navigation working through the projected names.


What you can and can't do in a projection

  • Expose or hide fields — list only what consumers need. Hidden fields still exist in the interface view for other projections or internal logic.
  • Rename for consumers — alias a cryptic backend field to a friendly name without touching the model.
  • Add UI annotations — @UI.lineItem, @UI.identification, value helps. Best practice: keep them in a separate metadata extension (.ddlx) so the projection stays clean and UI metadata can evolve independently.
  • Redirect associations — navigation targets must point at projected entities, not interface ones.
  • Can't: change the data model itself. New fields, new associations, changed keys — those belong in the interface view.

Why the separation matters

Without it, every UI tweak risks the data model. A renamed field breaks an API consumer; a hidden column breaks a report. The two-layer design gives you a stable contract (interface) and a flexible surface (projection).

The behavior projection (the projection; BDEF) mirrors this: it re-exposes operations with use create;, use update;, use etag — deciding which capabilities each service gets. Data layer, behavior layer, each projected independently.

Rule of thumb: if the change is about what data exists, edit the interface view. If it's about what a consumer sees, edit the projection.

Which layer do you reach for first when a Fiori app needs a new column? If the answer is "the projection," your layering instincts are already right.