RAP Services, OData & Fiori Elements

35.1 Projection layer

Projection behavior:

(ZC_Booking is the projection of ZR_Booking with _Travel : redirected to parent ZC_Travel.)

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Travel - projection'
@Metadata.allowExtensions: true
@Search.searchable: true
define root view entity ZC_Travel
  provider contract transactional_query
  as projection on ZR_Travel
{
  key TravelUUID,
      @Search.defaultSearchElement: true
      TravelID,
      @Consumption.valueHelpDefinition: [{ entity: { name: '/DMO/I_Agency', element: 'AgencyID' } }]
      AgencyID,
      CustomerID,
      BeginDate,
      EndDate,
      TotalPrice,
      CurrencyCode,
      OverallStatus,
      LocalLastChangedAt,
      _Booking : redirected to composition child ZC_Booking
}
projection;
strict ( 2 );
use draft;

define behavior for ZC_Travel alias Travel
{
  use create;
  use update;
  use delete;
  use action acceptTravel;
  use action rejectTravel;
  use action Edit;
  use action Activate;
  use action Discard;
  use action Resume;
  use action Prepare;
  use association _Booking { create; with draft; }
}

define behavior for ZC_Booking alias Booking
{
  use update;
  use delete;
  use association _Travel { with draft; }
}

35.2 UI annotations (metadata extension)

@Metadata.layer: #CUSTOMER
@UI.headerInfo: { typeName: 'Travel', typeNamePlural: 'Travels', title: { value: 'TravelID' } }
annotate entity ZC_Travel with
{
  @UI.facet: [ { id: 'Travel', purpose: #STANDARD, type: #IDENTIFICATION_REFERENCE, label: 'Travel', position: 10 },
               { id: 'Booking', purpose: #STANDARD, type: #LINEITEM_REFERENCE, label: 'Bookings',
                 position: 20, targetElement: '_Booking' } ]
  @UI.hidden: true
  TravelUUID;
  @UI: { lineItem: [ { position: 10 } ], identification: [ { position: 10 } ], selectionField: [ { position: 10 } ] }
  TravelID;
  @UI: { lineItem: [ { position: 20 } ], identification: [ { position: 20 } ], selectionField: [ { position: 20 } ] }
  AgencyID;
  @UI: { lineItem: [ { position: 30 } ], identification: [ { position: 30 } ] }
  CustomerID;
  @UI: { lineItem: [ { position: 40 } ], identification: [ { position: 40 } ] }
  BeginDate;
  @UI: { lineItem: [ { position: 50 } ], identification: [ { position: 50 } ] }
  EndDate;
  @UI: { lineItem: [ { position: 60 },
                     { type: #FOR_ACTION, dataAction: 'acceptTravel', label: 'Accept' },
                     { type: #FOR_ACTION, dataAction: 'rejectTravel',
…

35.3 Service definition and binding

Then create a service binding (ZUI_TRAVEL_O4) with binding type OData V4 – UI (or V2 – UI, V4/V2 – Web API), publish it (on-premise: local service endpoint; transaction /IWFND/V4_ADMIN for V4 service groups), and click Preview to open a generated Fiori elements list report/object page — no UI code needed.

@EndUserText.label: 'Travel service'
define service ZUI_TRAVEL_O4 {
  expose ZC_Travel  as Travel;
  expose ZC_Booking as Booking;
  expose /DMO/I_Agency as Agency;
}

35.4 OData basics

OData is a REST protocol: entity sets as URLs, CRUD via HTTP verbs, query options.

/Travel?$filter=OverallStatus eq 'O'&$orderby=BeginDate desc&$top=20 /Travel with JSON body

35.5 SEGW (legacy Gateway service builder)

Before RAP, OData V2 services were built in SEGW (SAP Gateway Service Builder): define entity types and sets (manually, from DDIC, or by referencing CDS via @OData.publish: true), generate MPC (model provider) and DPC (data provider) classes, and redefine methods in …_DPC_EXT:

Register with /IWFND/MAINT_SERVICE, test with /IWFND/GW_CLIENT, check errors in /IWFND/ERROR_LOG. SEGW and @OData.publish are legacy; use RAP for new services.

Manual entity model / DDIC CDS view entities DPC_EXT methods (CRUD per entity) Behavior definition + handlers V2 (V4 limited)

METHOD travelset_get_entityset.
  SELECT * FROM ztravel INTO CORRESPONDING FIELDS OF TABLE @et_entityset UP TO 100 ROWS.
ENDMETHOD.

35.6 SAP Fiori elements basics

SAP Fiori is SAP's UX design system; Fiori elements are metadata-driven floorplans rendered from OData + annotations:

List Report & Object Page Search, list, and edit business objects (most common) Simple task lists Analytical List Page Analytics + transactions Form Entry Object Page

Generate a deployable app with SAP Business Application Studio or VS Code + SAP Fiori tools (Application Generator → select your service → floorplan), then deploy to the ABAP repository (BSP application) or BTP HTML5 repository and add it to the Fiori Launchpad (catalogs, groups/spaces and pages; IAM apps in the cloud). Freestyle SAPUI5 is used when floorplans don't fit.