RAP from scratch · Lesson 3 of 6
Your first OData service in RAP: projection, Service Definition and Service Binding
Expose the library as an OData V4 service and open it in a Fiori Elements preview app, without writing any UI5.
We already have the data model (ZR_LibBook). Now we publish it so a Fiori app can consume it. It takes four objects, always in the same order:
ZR_LibBook Root View Entity (lesson 2)
└─ ZC_LibBook Projection: which fields this app sees
├─ ZC_LibBook Metadata Extension: how they are displayed
└─ ZUI_LIB_BOOK Service Definition: which entities the service exposes
└─ ZUI_LIB_BOOK_O4 Service Binding: which protocol (OData V4 UI)
1. The projection (C_)
The projection is the view for one specific consumer. The Root View Entity stays generic; each app (or API) gets its own projection with what it needs.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.allowExtensions: true
@EndUserText.label: 'Library: books (app)'
@Search.searchable: true
define root view entity ZC_LibBook
provider contract transactional_query
as projection on ZR_LibBook
{
key BookUuid,
@Search.defaultSearchElement: true
BookId,
@Search.defaultSearchElement: true
@Search.fuzzinessThreshold: 0.8
Title,
AuthorId,
_Author.Name as AuthorName,
Pages,
Isbn,
Rating,
Price,
CurrencyCode,
LocalLastChangedAt
}
as projection on ZR_LibBook: it does not read tables; it builds on the root entity.provider contract transactional_query: says this projection serves a transactional app. In lesson 4 we will add behavior to it (create, update, delete)._Author.Name as AuthorName: uses the association from lesson 2 to bring in the author’s name. It is read-only.@Search.*: enables the app’s search box on the ID and the title;fuzzinessThresholdtolerates small typos.
2. The Metadata Extension: how it looks
The @UI annotations could live in the projection, but moving them to a Metadata Extension (MDE) keeps the view clean. That is what @Metadata.allowExtensions: true allows.
In ADT: right-click ZC_LibBook → New Metadata Extension.
@Metadata.layer: #CUSTOMER
@UI.headerInfo: {
typeName: 'Book',
typeNamePlural: 'Books',
title: { type: #STANDARD, value: 'Title' },
description: { value: 'AuthorName' }
}
annotate entity ZC_LibBook with
{
@UI.facet: [ {
id: 'Book',
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'Book',
position: 10
} ]
@UI.hidden: true
BookUuid;
@UI: { lineItem: [ { position: 10 } ], identification: [ { position: 10 } ], selectionField: [ { position: 10 } ] }
BookId;
@UI: { lineItem: [ { position: 20 } ], identification: [ { position: 20 } ] }
Title;
@UI: { lineItem: [ { position: 30 } ], identification: [ { position: 30 } ], selectionField: [ { position: 20 } ] }
AuthorId;
@UI: { lineItem: [ { position: 40 } ], identification: [ { position: 40 } ] }
AuthorName;
@UI: { lineItem: [ { position: 50 } ], identification: [ { position: 50 } ] }
Pages;
@UI: { lineItem: [ { position: 60 } ], identification: [ { position: 60 } ] }
Rating;
@UI: { lineItem: [ { position: 70 } ], identification: [ { position: 70 } ] }
Price;
@UI.hidden: true
LocalLastChangedAt;
}
| Annotation | Where it shows up |
|---|---|
lineItem |
Column in the list table |
selectionField |
Filter in the list’s top bar |
identification + facet |
Field on the detail page (Object Page) |
headerInfo |
Title and subtitle of the detail page |
hidden |
Not displayed |
The currency needs no annotation of its own: since Price has @Semantics.amount.currencyCode, Fiori shows it next to the amount.
3. Service Definition: what is exposed
New → Other ABAP Repository Object → Business Services → Service Definition:
@EndUserText.label: 'Library: book service'
define service ZUI_LIB_BOOK {
expose ZC_LibBook as Book;
}
as Book is the entity set name in the service: that is how it will appear in the OData URL and in the preview.
4. Service Binding: which protocol
New → Other ABAP Repository Object → Business Services → Service Binding:
- Name:
ZUI_LIB_BOOK_O4 - Binding Type:
OData V4 - UI - Service Definition:
ZUI_LIB_BOOK
Then:
- Activate the binding.
- Click Publish (local service publication).
- In the entity list, select Book and click Preview.
A Fiori Elements app (List Report and Object Page) generated from your annotations opens in the browser. Click Go to list the books and open one to see its details.
The
_O4suffix (OData V4) and the UI type are a useful convention: the same Service Definition can get a secondWeb APIbinding for integrations, without UI annotations.
If something does not show up
| Symptom | Usual cause |
|---|---|
| The list is empty or has no columns | @Metadata.allowExtensions: true is missing in the projection, or the MDE is not activated |
Activation error on _Author.Name |
The _Author association is not listed at the end of ZR_LibBook |
| The Preview button is disabled | The binding is not published, or no entity is selected |
| You cannot create or edit | Expected: there is no behavior yet. We add it in lesson 4 |
Summary
With four objects and no JavaScript you have a read-only app with filters, search and a detail page. In the next lesson we give it behavior: creating and changing books, with validations that reject bad data.
Get new tutorials by email
One email when something new is published. No spam; unsubscribe anytime.
I will email you to confirm your subscription. Data handled under the privacy policy.