← Back to tutorials

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.

También disponible en español →

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; fuzzinessThreshold tolerates 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:

  1. Activate the binding.
  2. Click Publish (local service publication).
  3. 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 _O4 suffix (OData V4) and the UI type are a useful convention: the same Service Definition can get a second Web API binding 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.