Manual creation of all RAP artifacts is time-consuming: Tables, CDS Views, Behavior Definitions, Service Bindings - this quickly adds up to a dozen objects. With the RAP Generators in ADT and the Fiori Elements App Generator, you can dramatically accelerate this process.
Why Code Generation?
A complete RAP stack with draft handling typically includes:
1. Database table2. Draft table3. Interface CDS View4. Projection CDS View5. Metadata Extension6. Behavior Definition7. Behavior Implementation8. Service Definition9. Service BindingCreating these nine objects manually and linking them correctly takes time - especially with consistent naming conventions and correct syntax. The RAP Generator creates all of this in a few clicks.
RAP Generator in ADT
The RAP Generator is directly integrated into ABAP Development Tools (ADT) and generates complete RAP Business Objects from table definitions.
Prerequisites
- SAP S/4HANA 2022 or newer
- SAP BTP ABAP Environment
- ABAP Development Tools (Eclipse)
Step 1: Start Generator
Right-click on database table→ Generate ABAP Repository Objects→ Generate RAP BOAlternatively:
Right-click on package→ New → Other ABAP Repository Object→ Business Services → Generate RAP BOStep 2: Select Table
Select the main table for your Business Object. For our flight booking example:
Table: ZFLIGHT_BOOKThe generator automatically recognizes:
- Key fields
- Administrative fields (created_by, last_changed_at, etc.)
- Associations to other tables
Step 3: Generation Options
| Option | Description | Recommendation |
|---|---|---|
| Implementation Type | Managed or Unmanaged | Managed for standard cases |
| Draft Handling | With or without draft | With draft for editing apps |
| Data Model | Single or Hierarchy | Hierarchy for parent-child |
| Projection | With projection layer | Yes for UI applications |
For the flight booking scenario:
Implementation Type: ManagedDraft Handling: YesData Model: Single BOProjection: YesStep 4: Configure Names
The generator suggests names based on the table:
Table: ZFLIGHT_BOOKInterface View: ZI_FLIGHTBOOKProjection View: ZC_FLIGHTBOOKBehavior Def: ZI_FLIGHTBOOKService Definition: ZUI_FLIGHTBOOKService Binding: ZUI_FLIGHTBOOK_O4Customize according to your naming conventions - consistent prefixes are important:
I_ = Interface LayerC_ = Consumption/Projection LayerUI_ = UI Service_O4 = OData V4Step 5: Execute Generation
After clicking “Finish,” all objects are created:
┌─────────────────────────────────────────────────────────┐│ Generated Objects │├─────────────────────────────────────────────────────────┤│ ✓ ZDRAFT_FLIGHT_BOOK (Draft table) ││ ✓ ZI_FLIGHTBOOK (Interface CDS View) ││ ✓ ZI_FLIGHTBOOK (Behavior Definition) ││ ✓ ZBP_I_FLIGHTBOOK (Behavior Implementation) ││ ✓ ZC_FLIGHTBOOK (Projection CDS View) ││ ✓ ZC_FLIGHTBOOK (Projection Behavior) ││ ✓ ZUI_FLIGHTBOOK (Service Definition) ││ ✓ ZUI_FLIGHTBOOK_O4 (Service Binding) │└─────────────────────────────────────────────────────────┘Understanding Generated Artifacts
Interface CDS View
The generator creates a complete Interface View:
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Flight Booking'define root view entity ZI_FlightBook as select from zflight_book{ key booking_uuid, flight_id, customer_id, booking_date, seat_number, status, price, currency_code, @Semantics.user.createdBy: true created_by, @Semantics.systemDateTime.createdAt: true created_at, @Semantics.user.lastChangedBy: true last_changed_by, @Semantics.systemDateTime.lastChangedAt: true last_changed_at, @Semantics.systemDateTime.localInstanceLastChangedAt: true local_last_changed}Important: @Semantics annotations are automatically set for known field names.
Behavior Definition
managed implementation in class zbp_i_flightbook unique;strict ( 2 );with draft;
define behavior for ZI_FlightBook alias FlightBookpersistent table zflight_bookdraft table zdraft_flight_booketag master LocalLastChangedlock master total etag LastChangedAtauthorization master ( global ){ field ( readonly ) BookingUUID, CreatedBy, CreatedAt, LastChangedBy, LastChangedAt, LocalLastChanged;
field ( numbering : managed ) BookingUUID;
create; update; delete;
draft action Activate optimized; draft action Discard; draft action Edit; draft action Resume; draft determine action Prepare;}Behavior Implementation
The generated class contains scaffolding for local handlers:
CLASS lhc_FlightBook DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS: get_global_authorizations FOR GLOBAL AUTHORIZATION IMPORTING REQUEST requested_authorizations FOR FlightBook RESULT result.ENDCLASS.
CLASS lhc_FlightBook IMPLEMENTATION. METHOD get_global_authorizations. " Implement your own authorization checks here ENDMETHOD.ENDCLASS.Customizing Generated Objects
After generation, you typically need to extend the objects:
1. Add UI Annotations
In the Projection View or Metadata Extension:
@UI.headerInfo: { typeName: 'Flight Booking', typeNamePlural: 'Flight Bookings', title: { value: 'FlightID' }}
@UI.lineItem: [{ position: 10 }]@UI.identification: [{ position: 10 }]FlightID;
@UI.lineItem: [{ position: 20 }]@UI.selectionField: [{ position: 10 }]BookingDate;2. Add Validations
In the Behavior Definition:
define behavior for ZI_FlightBook alias FlightBook...{ validation validateBookingDate on save { field BookingDate; } validation validateSeat on save { field SeatNumber; }}In the Implementation:
METHOD validateBookingDate. READ ENTITIES OF zi_flightbook IN LOCAL MODE ENTITY FlightBook FIELDS ( BookingDate ) WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
LOOP AT bookings INTO DATA(booking). IF booking-BookingDate < cl_abap_context_info=>get_system_date( ). APPEND VALUE #( %tky = booking-%tky ) TO failed-flightbook. APPEND VALUE #( %tky = booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Booking date must be in the future' ) %element-BookingDate = if_abap_behv=>mk-on ) TO reported-flightbook. ENDIF. ENDLOOP.ENDMETHOD.3. Add Custom Actions
define behavior for ZI_FlightBook alias FlightBook...{ action confirmBooking result [1] $self; action cancelBooking result [1] $self;}Fiori Elements App Generator
After the RAP backend, you can generate the frontend with the Fiori Elements App Generator.
In Business Application Studio
1. Open Command Palette (F1)2. Enter "Fiori: Open Application Generator"3. Select template: "List Report Page" or "Worklist"4. Data source: Select OData V4 Service5. Enter Service Binding: ZUI_FLIGHTBOOK_O46. Select main entity: FlightBook7. Assign project nameGenerated App Structure
flight-booking-app/├── webapp/│ ├── manifest.json # App configuration│ ├── Component.js # UI5 Component│ ├── index.html # Start page│ └── localService/ # Mock data├── package.json # Dependencies└── ui5.yaml # Build configurationCustomize manifest.json
The most important customizations:
{ "sap.app": { "title": "{{appTitle}}", "description": "{{appDescription}}" }, "sap.ui5": { "routing": { "targets": { "FlightBookList": { "options": { "settings": { "initialLoad": true, "variantManagement": "Page" } } } } } }}Generator vs. Manual: Decision Guide
| Scenario | Generator | Manual |
|---|---|---|
| New greenfield project | Recommended | No |
| Standard CRUD app | Recommended | No |
| Complex hierarchies | Partially | Partly customization needed |
| Migration from legacy | No | Yes, for control |
| Unmanaged scenario | Limited | Mostly manual |
| Learning/Training | No | Yes, for understanding |
| Prototyping | Recommended | No |
When to Use Generator?
Recommended:
- New standard applications
- Managed scenario with draft
- Quick prototypes
- Consistent naming conventions important
Prefer Manual:
- Unmanaged with legacy integration
- Complex BO hierarchies
- Special structural requirements
- Learning projects for RAP understanding
Typical Customizations After Generation
Checklist for Generated Objects
Customize after generation:
□ Interface View □ @EndUserText.label for all fields □ Associations to other entities □ @ObjectModel.text for text fields
□ Projection View □ Define @UI.headerInfo □ @UI.lineItem for List Report □ @UI.identification for Object Page □ @UI.selectionField for filters
□ Behavior Definition □ Add validations □ Determinations for default values □ Define custom actions □ Configure authorization checks
□ Service Binding □ Activate publish □ Test preview in browserBest Practices
1. Generate, Then Customize
Use the generator as a starting point - not as a finished product:
Generator → Scaffold → Customization → Testing → Refinement2. Define Naming Conventions First
Before you generate, define prefixes:
Z = Customer namespaceI_ = Interface LayerC_ = Consumption LayerA_ = Abstract EntityUI_ = UI Service_O4 = OData V43. Generator for Consistency
Even with manual development: Use the generator once to see the expected structure - then you can build consistently.
4. Use Version Control
Commit directly after each generation - this way you can track changes:
# After generationgit add .git commit -m "feat: generated RAP BO for FlightBooking"
# After customizationsgit commit -m "feat: added validations and UI annotations"Conclusion
The RAP generators save significant time when creating standard applications. The key is proper use:
- Generator for scaffold - Structure and boilerplate
- Manual customization - Business logic and UI refinement
- Iterative approach - Generate, test, customize
For beginners, it’s still recommended to create all objects manually once - this way you understand what the generator does in the background. After that, you can use the generators effectively.
Related Articles
- RAP End-to-End Tutorial - Complete tutorial with manual setup
- SAP Fiori Elements UI - UI generation from annotations
- ADT Tips & Tricks - Efficient development in Eclipse
- RAP Managed vs Unmanaged - The right architecture decision