Skip to content

Lesson 16 Companion — RAP Projection and OData V4 ​

This companion supports:

text
Lesson 16 — RAP Projection, Value Help, Metadata, and OData V4

Use it as:

text
syntax reference
instructor guide
troubleshooting reference
service-layer architecture guide

1. Full architecture ​

text
ZRESV_###
    ↓
ZR_RESERVATION_###
    ↓
ZC_RESERVATION_###
    ↓
Projection BDEF
    ↓
ZUI_RESERVATION_###
    ↓
ZUI_RESV_###_O4
    ↓
OData V4 UI
    ↓
Fiori Elements Preview

Read protection exists on both:

text
ZR_RESERVATION_###
ZC_RESERVATION_###

2. Why projection exists ​

The base BO should remain reusable.

The projection adapts it for a specific consumer.

Typical projection concerns:

text
field subset
aliases
search
value help
texts
UI-facing semantics
service-specific calculated/virtual elements

3. Projection CDS reference ​

abap
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Reservation Service Projection'
@Metadata.allowExtensions: true
@Search.searchable: true

define root view entity ZC_Reservation_###
  provider contract transactional_query
  as projection on ZR_Reservation_###
{
  key Uuid,

      @Search.defaultSearchElement: true
      ReservationNo,

      @Search.defaultSearchElement: true
      CustomerName,

      CustomerEmail,
      WorkshopCode,
      ReservationDate,
      Status,
      ResponsibleUser,

      Fee,

      @Consumption.valueHelpDefinition: [
        {
          entity: {
            name: 'I_CurrencyStdVH',
            element: 'Currency'
          },
          useForValidation: true
        }
      ]
      CurrencyCode,

      Notes,
      LocalCreatedBy,
      LocalCreatedAt,
      LocalLastChangedBy,
      LocalLastChangedAt,
      LastChangedAt
}

4. Provider contract ​

Use:

abap
provider contract transactional_query

for a service-facing RAP BO projection.

Do not omit the provider contract.

Current projection-view modeling expects an explicit provider contract.


5. Projection root ​

Because:

text
ZR_RESERVATION_###

is a root entity, its service-facing projection is also:

text
root

For multi-node BOs, the composition structure must be projected consistently.

That comes later in Lesson 18.


6. Projection elements ​

A projection can select a subset.

Example:

text
base BO contains 20 fields
service projection exposes 12

The service does not have to reveal every base element.

Lesson 16 exposes nearly everything for easier inspection.


7. Projection cannot invent persistence ​

The projection is not a new table.

It does not create:

text
a second database row
a second UUID
a second transaction

It adapts the same BO.


8. Search reference ​

View-level:

abap
@Search.searchable: true

Element-level:

abap
@Search.defaultSearchElement: true
ReservationNo,

Use default search only for fields that make sense for broad user search.


9. Value-help reference ​

abap
@Consumption.valueHelpDefinition: [
  {
    entity: {
      name: 'I_CurrencyStdVH',
      element: 'Currency'
    },
    useForValidation: true
  }
]
CurrencyCode,

The provider is:

text
I_CurrencyStdVH

and the mapped element is:

text
Currency

10. Value help vs validation ​

Value help:

text
helps the consumer choose

Validation:

text
protects backend validity

Do not remove:

text
validateFee

because CurrencyCode has a value help.


11. Value-help provider exposure ​

The Service Definition must expose the provider:

abap
expose I_CurrencyStdVH as Currencies;

Otherwise the OData consumer cannot use the provider through the service.


12. DCL does not automatically propagate ​

A critical CDS rule:

text
Access Control on an underlying CDS entity
does not automatically protect a higher CDS entity.

Therefore:

text
ZR_RESERVATION_###
DCL

does not automatically secure:

text
ZC_RESERVATION_###

13. Projection DCL reference ​

abap
@EndUserText.label: 'Reservation Projection Access'
@MappingRole: true
define role ZC_Reservation_###
{
  grant select on ZC_Reservation_###
    where inheriting conditions from entity ZR_Reservation_###;
}

This reuses the base access condition.


14. Why inheritance is better than duplication ​

Duplicating:

abap
where ResponsibleUser = aspect user

would work conceptually.

But it creates two maintained copies of one policy.

Inheritance gives:

text
base DCL
→ authorization source

projection DCL
→ reuse

15. DCL troubleshooting ​

If the projection reveals too much data:

text
Is #CHECK present?
Is projection DCL active?
Does the DCL protect ZC_RESERVATION_###?
Does it inherit from the correct base entity?

Do not assume the base DCL is enough.


16. Projection BDEF reference ​

abap
projection;
strict ( 2 );

define behavior for ZC_Reservation_### alias Reservation
use etag
{
  use create;
  use update;
  use delete;

  use action confirm;
  use action cancel;
}

17. What projection; means ​

The BDEF does not define:

text
managed implementation
unmanaged implementation

It projects behavior from an existing BO.


18. What use create means ​

It means:

text
this service projection exposes base CREATE

It does not mean:

text
implement CREATE again

The managed base BO still implements it.


19. What use update and use delete mean ​

Same pattern:

text
base supports operation
projection chooses to expose operation

A different service could intentionally omit one.


20. What use action means ​

Base action:

text
confirm

already has:

text
implementation
feature control
authorization
messages

Projection:

abap
use action confirm;

makes it part of this service-facing BO projection.


21. Reused authorization ​

CRUD operations and base actions reused with:

text
use

retain base authorization control.

You do not write a second:

text
get_instance_authorizations

for this simple projection.


22. Reused feature control ​

The service continues to receive Lesson 14 feature behavior.

Example:

text
Status = C
→ confirm disabled
→ Fee read-only

No projection feature implementation is needed.


23. Reused validations and determinations ​

Projection behavior reaches the same base BO.

Therefore:

text
setInitialStatus
validateCustomer
validateDate
validateFee

still execute where appropriate.


24. ETag projection ​

Use:

abap
use etag

when the underlying entity has an ETag and the service should expose that concurrency behavior.

The ETag type is inherited from the base behavior.


25. Why concurrency matters in services ​

Two consumers can edit the same data.

ETag behavior helps detect:

text
stale client version
concurrent modification

Lesson 16 does not implement a custom locking algorithm.

It exposes the existing RAP concurrency model.


26. Metadata extension prerequisite ​

Projection:

abap
@Metadata.allowExtensions: true

must be present.

Then a separate metadata extension can annotate it.


27. Metadata extension reference ​

abap
@Metadata.layer: #CORE

@UI.headerInfo: {
  typeName: 'Reservation',
  typeNamePlural: 'Reservations',
  title: {
    type: #STANDARD,
    value: 'ReservationNo'
  }
}

annotate entity ZC_Reservation_### with
{
  @UI.facet: [
    {
      id: 'Reservation',
      purpose: #STANDARD,
      type: #IDENTIFICATION_REFERENCE,
      label: 'Reservation',
      position: 10
    }
  ]
  @UI.lineItem: [
    { position: 10, label: 'Reservation' }
  ]
  @UI.identification: [
    { position: 10, label: 'Reservation' }
  ]
  ReservationNo;

  @UI.lineItem: [
    { position: 20, label: 'Customer' }
  ]
  @UI.identification: [
    { position: 20, label: 'Customer' }
  ]
  CustomerName;

  @UI.identification: [
    { position: 30, label: 'Customer Email' }
  ]
  CustomerEmail;

  @UI.lineItem: [
    { position: 30, label: 'Workshop' }
  ]
  @UI.identification: [
    { position: 40, label: 'Workshop' }
  ]
  WorkshopCode;

  @UI.lineItem: [
    { position: 40, label: 'Reservation Date' }
  ]
  @UI.identification: [
    { position: 50, label: 'Reservation Date' }
  ]
  @UI.selectionField: [
    { position: 20 }
  ]
  ReservationDate;

  @UI.lineItem: [
    { position: 50, label: 'Status' },
    { position: 90, type: #FOR_ACTION, dataAction: 'confirm', label: 'Confirm' },
    { position: 100, type: #FOR_ACTION, dataAction: 'cancel', label: 'Cancel' }
  ]
  @UI.identification: [
    { position: 60, label: 'Status' },
    { position: 110, type: #FOR_ACTION, dataAction: 'confirm', label: 'Confirm' },
    { position: 120, type: #FOR_ACTION, dataAction: 'cancel', label: 'Cancel' }
  ]
  @UI.selectionField: [
    { position: 10 }
  ]
  Status;

  @UI.lineItem: [
    { position: 60, label: 'Fee' }
  ]
  @UI.identification: [
    { position: 70, label: 'Fee' }
  ]
  Fee;

  @UI.lineItem: [
    { position: 70, label: 'Currency' }
  ]
  @UI.identification: [
    { position: 80, label: 'Currency' }
  ]
  @UI.selectionField: [
    { position: 30 }
  ]
  CurrencyCode;

  @UI.lineItem: [
    { position: 80, label: 'Responsible User' }
  ]
  @UI.identification: [
    { position: 90, label: 'Responsible User' }
  ]
  ResponsibleUser;

  @UI.identification: [
    { position: 100, label: 'Notes' }
  ]
  Notes;
}

28. @UI.headerInfo ​

This metadata helps the generated object page identify:

text
singular entity name
plural entity name
title field

Here the title is:

text
ReservationNo

29. @UI.lineItem ​

Controls list-report columns.

Position values:

text
10
20
30
...

make ordering easy to maintain.


30. @UI.identification ​

Describes important object-page fields.

It is not a database constraint.

It is UI metadata.


31. @UI.selectionField ​

Marks useful filter fields.

Lesson 16 uses:

text
Status
ReservationDate
CurrencyCode

32. Metadata layer ​

Use:

abap
@Metadata.layer: #CORE

for the course-owned core UI metadata extension.

Later extension scenarios can introduce other metadata layers.


33. Service Definition reference ​

abap
@EndUserText.label: 'Reservation UI Service'
define service ZUI_RESERVATION_###
{
  expose ZC_Reservation_### as Reservations;
  expose I_CurrencyStdVH    as Currencies;
}

33A. Action UI metadata ​

Exposing an action in the projection BDEF makes it part of the OData behavior contract, but a Fiori Elements action button also needs UI metadata.

Use a record such as:

abap
{ type: #FOR_ACTION, dataAction: 'confirm', label: 'Confirm' }

inside:

text
@UI.lineItem

for the list report and/or:

text
@UI.identification

for the object page.

The dataAction value must match the action name exposed by the projection behavior, unless an external action name is defined.


34. Service Definition responsibility ​

It chooses:

text
which CDS entities participate in the service

It does not choose:

text
OData version
UI vs Web API

35. Alias benefit ​

The service exposes:

text
Reservations
Currencies

instead of leaking all internal technical entity names to the service consumer.

Aliases make the service contract clearer.


36. Service Binding reference ​

Suggested:

text
ZUI_RESV_###_O4

Properties:

text
Service Definition:
ZUI_RESERVATION_###

Type:
OData V4

Category:
UI

37. Service Binding responsibility ​

Binding decides:

text
protocol
consumer category
local service endpoint
publish
preview

This is why:

text
Definition = what
Binding = how

is a useful memory rule.


38. Why OData V4 ​

OData V4 has broader RAP UI capabilities than V2.

For example:

text
value help
feature control exposure
modern UI service support

SAP recommends V4 where possible for transactional services.


39. Publishing ​

The binding must be active.

Then choose:

text
Publish

in the Service Binding editor.

This publishes the service locally in the current development system.


40. Publish is not deployment ​

Publishing the local endpoint is not:

text
deploying a launchpad app
transporting to production
assigning business roles

Those are separate lifecycle concerns.


41. Fiori Elements Preview ​

The Service Binding editor can launch:

text
Preview

for a UI binding.

The preview interprets:

text
OData metadata
UI annotations
RAP behavior

to generate a test UI.


42. Preview troubleshooting ​

If preview does not open:

text
binding active?
service published?
projection active?
projection BDEF active?
service definition active?
metadata extension active?

43. Empty preview troubleshooting ​

Check Lesson 15 DCL.

A service can be correct but return:

text
zero rows

because the current user owns no rows.

Create or keep an owned test Reservation.


44. Missing action troubleshooting ​

Check:

text
base BDEF contains action?
projection BDEF has use action?
action feature permits it?
authorization permits it?

Do not start by modifying UI metadata.


45. Missing currency value help ​

Check all three:

text
CurrencyCode has @Consumption.valueHelpDefinition
provider entity/element names are correct
provider is exposed in Service Definition

46. Wrong fields in list ​

Check:

text
metadata extension active?
@Metadata.allowExtensions true?
@UI.lineItem annotations?
correct entity name?

47. Wrong read authorization ​

Check:

text
projection @AccessControl... = #CHECK
projection DCL exists
inheritance source = ZR_RESERVATION_###
base DCL still active

48. Wrong modification authorization ​

Do not fix projection DCL.

Check:

text
base BDEF authorization
ResponsibleUser
get_global_authorizations
get_instance_authorizations
action authorization delegation

Read authorization and write authorization are different layers.


49. Why no projection authorization handler? ​

This lesson reuses base CRUD/actions.

Reused behavior inherits base authorization.

A new action defined only on projection level could require projection-level authorization design.

That is not needed here.


50. Why no new Behavior Pool? ​

Projection BDEF uses:

text
existing base behavior

There is no new managed persistence implementation.

So the projection does not need another behavior pool for reused operations.


51. UI metadata vs business logic ​

Metadata:

text
column order
labels
filters
object title

Business logic:

text
validity
status transitions
authorization
feature control

Do not mix them.


52. Service-specific surface ​

A second service could use another projection:

text
ZC_RESERVATION_API_###

and expose:

text
different fields
different actions
no UI annotations

while reusing the same base BO.

That is the architectural value of projection.


53. OData consumers do not bypass RAP ​

The flow is:

text
OData request
→ projected RAP behavior
→ base RAP behavior
→ transaction/save

It is not:

text
OData request
→ table directly

54. Validation through service ​

If the UI sends invalid data:

text
past ReservationDate

the same Lesson 13 validation runs.

The service carries the RAP message back to the consumer.


55. Determination through service ​

A create can omit:

text
Status

The same:

text
setInitialStatus

determination supplies:

text
N

No service-specific duplicate is needed.


56. Action through service ​

Projected:

text
confirm
cancel

call the same base action implementations used by EML consumers.

One BO behavior serves multiple consumers.


57. Feature control through OData V4 ​

Dynamic action/field features can be exposed to OData V4 UI services.

That lets the UI reflect:

text
enabled/disabled actions
editable/read-only fields

from backend state.


58. Authorization through service ​

DCL protects projected reads.

RAP authorization protects modifying requests.

The UI is not trusted to enforce backend authorization itself.


59. Non-draft UI limitation ​

The service is non-draft.

This is intentional.

Lesson 16 isolates:

text
projection
service
metadata
value help

before introducing draft lifecycle complexity.


60. Why Lesson 17 follows naturally ​

After Lesson 16, students can see:

text
the BO through a real UI service

Lesson 17 can then explain why transactional UI editing benefits from:

text
draft instances
Edit
Activate
Discard
Resume
Prepare

61. Certification relevance ​

A system-based task can present:

text
missing provider contract
missing projection operation
broken Service Definition
wrong service binding
missing value-help provider
unprotected projection DCL
broken metadata extension

Students need to identify the responsible layer quickly.


62. Certification object map ​

text
ZR_...
→ base business object model

ZC_...
→ service-specific projection

Projection BDEF
→ exposed behavior surface

DCL
→ read authorization

Metadata Extension
→ UI metadata

Service Definition
→ exposed entity set model

Service Binding
→ protocol/category/runtime endpoint

63. BTP Trial boundary ​

Fully reproducible:

text
projection
projection BDEF
projection DCL
metadata extension
service definition
OData V4 UI binding
local publish
preview

Not required:

text
productive launchpad deployment
enterprise identity setup
productive PFCG role lifecycle

64. Instructor demo sequence ​

Recommended:

text
1. F8 base root
2. Create projection
3. F8 projection
4. Explain DCL inheritance requirement
5. Create projection DCL
6. Create projection BDEF
7. Add Currency value help
8. Add metadata extension
9. Create Service Definition
10. Create OData V4 UI Binding
11. Publish
12. Preview
13. Search
14. Value help
15. Execute confirm
16. Observe feature change
17. Trigger validation message

65. Final review ​

Students should be able to explain:

text
why projection exists
why projection needs explicit provider contract
why projection needs its own read protection
why projection behavior uses `use`
why value-help provider must be exposed
why UI metadata belongs in metadata extension
what Service Definition does
what Service Binding does
why OData does not bypass base RAP behavior
why Draft is still missing