Skip to Content
Technical Articles
Author's profile photo Manasi Balagere

How to expose CDS View using RAP in SAP S/4HANA

SAP BTP (Business Technology Platform) ABAP Environment is an all-inclusive ABAP platform that is cloud ready.

PS: The reason I was inspired to write this blog was when I came across the term Steampunk which sounded so cool! But it has been brought to my attention that this term is now obsolete and so I am removing the references to avoid confusion.

Some clients have huge ABAP Repositories, and it is understandable if they would want to continue using it in S/4HANA environment as well. SAP BTP ABAP environment is what they would then use for the cloud ready developments. RESTful OData Services based on CDS (Core Data Services) views too can be created.

If someone told me that we could expose a custom SAP view through a browser 5 years ago, I would not have believed him/her and yet here I am, about to do exactly that; expose a CDS View without even explicitly creating an OData service. The below is the outcome you will reap if you follow this blog post till the end. Isn’t it cool? So, what are we waiting for!! Let’s dive in…

Here is a comprehensive step-by-step guide with screenshots to create a CDS view and expose it:

  1. Open Eclipse IDE (ABAP Development Tools) and login to your system (called project in ADT terms)

2. Create a new Data Definition


3. No transport request (TR) is selected as this is a local object. But if yours is an object that is not local, here is where you select a transport request.

4. We will be creating a view with association, so you need to select that option and click on finish. Association is an on-demand join which is executed only when the data is accessed (also called the lazy approach; prerequisite is that the association needs to be made public).

5. Below is the code.

@EndUserText.label:'CDS View for flight booking'
defineview ztest_flight_cds 
asselectfrom sbook as Booking
association[0..1]to I_Country  as _Country  on$ = _Country.Country
key carrid as FlightID,
key connid as ConnectionID,
key fldate as Flight_date,
key bookid as Booking,
     passname   as CustomerName,
     order_date as DateOfBooking,
     fldate     as DateOfTravel,
     forcurkey  as CurrencyCode,
     _Country // Make association public

6. Now add the UI annotations at the header level and for each field and the final code will be as follows. Copy paste below code in the editor.

@AbapCatalog.sqlViewName: 'ZVTESTFLIGHT'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'CDS View for flight booking'
@Search.searchable : true
    typeName: 'Booking',
    typeNamePlural: 'Bookings',
    title: { type: #STANDARD, value: 'Booking' }
define view ztest_flight_cds 
    as select from sbook as Booking
  association [0..1] to I_Country  as _Country  on $ = _Country.Country
          @UI.facet: [
          id:       'Booking',
          purpose:  #STANDARD,
          type:     #IDENTIFICATION_REFERENCE,
          label:    'Booking',
          position: 10 }

      @UI: {
          lineItem: [ { position: 10, importance: #HIGH, label: 'Flight ID' } ],
          identification:[ { position: 10, label: 'Flight ID' } ]
     key carrid as FlightID,
           @UI: {
          lineItem: [ { position: 20, importance: #HIGH, label: 'Connection ID' } ],
          identification:[ { position: 20, label: 'Connection ID' } ]
     key connid as ConnectionID,
           @UI: {
          lineItem: [ { position: 30, importance: #HIGH, label: 'Fl.Date' } ],
          identification:[ { position: 30, label: 'Fl.Date' } ]
     key fldate as Flight_date,
           @UI: {
          lineItem: [ { position: 40, importance: #HIGH, label: 'Booking ID' } ],
          identification:[ { position: 40, label: 'Booking ID' } ]
     key bookid as Booking,
           @UI: {
        lineItem: [ { position: 50, label: 'Customer', importance: #HIGH } ],
        identification:[ { position: 50, label: 'Customer' } ]
      @Search.defaultSearchElement: true
     passname   as CustomerName,
           @UI: {
           identification:[ { position: 60, label: 'Country' } ]
           @UI: {
           identification:[ { position: 60, label: 'Booked On' } ]
     order_date as DateOfBooking,
           @UI: {   identification:[ { position: 70, label: 'Traveling on' } ]    }
     fldate     as DateOfTravel,
           @UI: {
      lineItem: [ { position: 80, label: 'Cost', importance: #HIGH } ],
      identification:[ { position: 80, label: 'Cost' } ]
      @Semantics.amount.currencyCode: 'CurrencyCode'
           @UI: { identification:[ { position: 90, label: 'Currency' } ]     }
      @Semantics.currencyCode: true
     forcurkey  as CurrencyCode,
     _Country // Make association public

7. Activate the CDS View


8. We can test our CDS View with Data Preview. Right-click on the Data Definition and select Open with->Data Preview

Data is displayed as below:

Right click on any of the value, follow association, and we can see country data too

9. Now we will create service definition.

a. Right-click the Data Definition name and select ‘New Service Definition’.



b. No TR is required since this is a local object as well.

c. Click Finish.

d. Copy and paste the below code:

@EndUserText.label:'Service defnition for Flight CDS'
defineservice Ztest_flight_srvd {
expose ztest_flight_cds;
expose I_Country;

e. Activate the Service Definition

10. Now we will create the service binding

a. Right-click the service definition name and select ‘New Service Binding’

b. Click Finish

c. Click on Publish

The OData Service URL is automatically generated without us using SEGW transaction

d. Click on the service URL link

The above metadata is displayed

e. Select an entity and click on the Preview option

f. Click on settings and select all columns

g. Click OK

You still don’t see anything and no need to panic 😊

h. Just click on GO

Voila!! All the entries magically appear

i. Go back to the Eclipse and select the other entity this time and click on Preview

j. Repeat steps f. through h.

You see the above country entries from the Country view.

Hope you enjoyed reading this post as much as I enjoyed researching and writing it!! I would love to hear what you think, so please leave me your feedback.



Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Devraj Bardhan
      Devraj Bardhan

      I think we should start using the official product name -SAP BTP, ABAP environment on this platform.

      PS: Steampunk does sound like a Si-fi name 🙂

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      At this point I'm losing track of all the SAP renamings but I believe that "Steampunk aka RAP" is incorrect.

      In 2019, Steampunk was announced as the project name for SAP Cloud Platform ABAP Environment.

      Then SAP Cloud Platform was renamed to SAP BTP (Business Transformation Platform) and, by extension, Steampunk now refers to SAP BTP, ABAP Environment. ABAP RAP is part of it but that does not make them synonymous. RAP = RESTful Application Programming model. ABAP RAP can be used both on-premise and in Cloud, so not at all "aka Steampunk".

      I agree with Devraj that it helps to use the current official name, even though it's probably going to change twice by the time I finish writing this. 🙂

      This blog post seem to be outlining the textbook RAP implementation steps, not really sure it has much to do with Steampunk... But it is an interesting observation. Thank you for sharing!

      Author's profile photo Manasi Balagere
      Manasi Balagere
      Blog Post Author

      I can't agree more about the renamings :). Thanks for taking the time to provide the feedback. I have updated the blog post.

      Author's profile photo Andre Fischer
      Andre Fischer

      Hi Manasi,

      I have unfortunately to agree that wording in the SAP world in sometimes confusing and that we (SAP) have tendency to change our product names once in a while ;-).

      However you should rename your blog post from "How to expose CDS View using BTP ABAP" to "How to expose CDS View using RAP in SAP S/4HANA".

      The ABAP RESTful Application Programming Model (aka RAP) is available in on premise systems as of SAP S/4HANA 1909 but when it comes to develop applications in an on premise system compared to the development in a Steampunk System there are main differences.

      1. In a Steampunk system you are only allowed to read from your own tables, not from tables that have been delivered by SAP (such as sbook).
        Instead you would have to read the data from C1 released CDS views locally in your system that are shown under "released objects" or via remote API's if you are using a side-by-side scenario.
      2. For local development you cannot use $TMP in Steampunk but you would create your own package in the Z-namespaces in the software component ZLOCAL.
      3. Quite soon there will be a so called "Embedded Steampunk" that will allow local ABAP development in SAP S/4HANA Cloud systems. There one will be able to leverage C1 released API's from SAP to build applications.

      So your code would (in a similar fashion) also work in a Steampunk system (the nick name will be stable ;-)) when you would use a Z-table and your own pacakge in ZLOCAL.

      But when one would try to copy and paste it into a Steampunk system this would result in syntax errors.

      Kind regards,


      Author's profile photo Manasi Balagere
      Manasi Balagere
      Blog Post Author

      Thanks Andre for your clarification!

      Author's profile photo PARAMITA MUKHERJEE

      Hi Manasi,

      Thanks for the detailed explanation.

      Can you please clarify what is I_Country? I believe this is not a database table. Is this a different CDS entity?



      Author's profile photo Ali Faraz
      Ali Faraz

      Nice blog!

      Just one small thing you could add... in step 10, where we publish the service binding.. it is worth mentioning that it can also be published as any of following:

      1. V4 API

      2. V4 UI

      3. V2 UI

      4. V2 API