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.