Génération de code RAP : Utiliser le générateur ADT et Fiori Tools

Catégorie
RAP
Publié
Auteur
Johannes

La création manuelle de tous les artefacts RAP prend du temps : tables, CDS Views, Behavior Definitions, Service Bindings - cela s’additionne rapidement à une douzaine d’objets. Avec les générateurs RAP dans ADT et le générateur d’app Fiori Elements, vous pouvez considérablement accélérer ce processus.

Pourquoi la génération de code ?

Un stack RAP complet avec gestion Draft comprend typiquement :

1. Table de base de données
2. Table Draft
3. Interface CDS View
4. Projection CDS View
5. Metadata Extension
6. Behavior Definition
7. Behavior Implementation
8. Service Definition
9. Service Binding

Créer manuellement ces neuf objets et les connecter correctement prend du temps - en particulier avec des conventions de nommage cohérentes et une syntaxe correcte. Le générateur RAP crée tout cela en quelques clics.

Générateur RAP dans ADT

Le générateur RAP est directement intégré dans les ABAP Development Tools (ADT) et génère des Business Objects RAP complets à partir de définitions de tables.

Prérequis

  • SAP S/4HANA 2022 ou plus récent
  • SAP BTP ABAP Environment
  • ABAP Development Tools (Eclipse)

Étape 1 : Démarrer le générateur

Clic droit sur table de base de données
→ Generate ABAP Repository Objects
→ Generate RAP BO

Alternativement :

Clic droit sur package
→ New → Other ABAP Repository Object
→ Business Services → Generate RAP BO

Étape 2 : Sélectionner la table

Choisissez la table principale pour votre Business Object. Pour notre exemple de réservation de vol :

Table: ZFLIGHT_BOOK

Le générateur reconnaît automatiquement :

  • Les champs clés
  • Les champs administratifs (created_by, last_changed_at, etc.)
  • Les associations vers d’autres tables

Étape 3 : Options de génération

OptionDescriptionRecommandation
Implementation TypeManaged ou UnmanagedManaged pour cas standards
Draft HandlingAvec ou sans DraftAvec Draft pour apps d’édition
Data ModelSingle ou HiérarchieHiérarchie pour Parent-Child
ProjectionAvec couche ProjectionOui pour applications UI

Pour le scénario réservation de vol :

Implementation Type: Managed
Draft Handling: Yes
Data Model: Single BO
Projection: Yes

Étape 4 : Configurer les noms

Le générateur propose des noms basés sur la table :

Table: ZFLIGHT_BOOK
Interface View: ZI_FLIGHTBOOK
Projection View: ZC_FLIGHTBOOK
Behavior Def: ZI_FLIGHTBOOK
Service Definition: ZUI_FLIGHTBOOK
Service Binding: ZUI_FLIGHTBOOK_O4

Adapter selon vos conventions de nommage - les préfixes cohérents sont importants :

I_ = Couche Interface
C_ = Couche Consumption/Projection
UI_ = Service UI
_O4 = OData V4

Étape 5 : Exécuter la génération

Après clic sur “Finish”, tous les objets sont créés :

┌─────────────────────────────────────────────────────────┐
│ Objets générés │
├─────────────────────────────────────────────────────────┤
│ ✓ ZDRAFT_FLIGHT_BOOK (Table Draft) │
│ ✓ 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) │
└─────────────────────────────────────────────────────────┘

Comprendre les artefacts générés

Interface CDS View

Le générateur crée une Interface View complète :

@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 : Les annotations @Semantics sont automatiquement définies pour les noms de champs connus.

Behavior Definition

managed implementation in class zbp_i_flightbook unique;
strict ( 2 );
with draft;
define behavior for ZI_FlightBook alias FlightBook
persistent table zflight_book
draft table zdraft_flight_book
etag master LocalLastChanged
lock master total etag LastChangedAt
authorization 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

La classe générée contient des squelettes pour les handlers locaux :

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.
" Implémenter ici vos propres contrôles d'autorisation
ENDMETHOD.
ENDCLASS.

Adapter les objets générés

Après la génération, vous devez généralement étendre les objets :

1. Ajouter les annotations UI

Dans la Projection View ou Metadata Extension :

@UI.headerInfo: {
typeName: 'Réservation de vol',
typeNamePlural: 'Réservations de vol',
title: { value: 'FlightID' }
}
@UI.lineItem: [{ position: 10 }]
@UI.identification: [{ position: 10 }]
FlightID;
@UI.lineItem: [{ position: 20 }]
@UI.selectionField: [{ position: 10 }]
BookingDate;

2. Compléter les validations

Dans la Behavior Definition :

define behavior for ZI_FlightBook alias FlightBook
...
{
validation validateBookingDate on save { field BookingDate; }
validation validateSeat on save { field SeatNumber; }
}

Dans l’implémentation :

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 = 'La date de réservation doit être dans le futur' )
%element-BookingDate = if_abap_behv=>mk-on
) TO reported-flightbook.
ENDIF.
ENDLOOP.
ENDMETHOD.

3. Ajouter des Custom Actions

define behavior for ZI_FlightBook alias FlightBook
...
{
action confirmBooking result [1] $self;
action cancelBooking result [1] $self;
}

Générateur d’app Fiori Elements

Après le backend RAP, vous pouvez générer le frontend avec le générateur d’app Fiori Elements.

Dans Business Application Studio

1. Ouvrir Command Palette (F1)
2. Saisir "Fiori: Open Application Generator"
3. Choisir template : "List Report Page" ou "Worklist"
4. Source de données : Sélectionner service OData V4
5. Saisir Service Binding : ZUI_FLIGHTBOOK_O4
6. Choisir entité principale : FlightBook
7. Attribuer nom de projet

Structure d’app générée

flight-booking-app/
├── webapp/
│ ├── manifest.json # Configuration app
│ ├── Component.js # Composant UI5
│ ├── index.html # Page de démarrage
│ └── localService/ # Données mock
├── package.json # Dépendances
└── ui5.yaml # Configuration build

Adapter manifest.json

Les adaptations les plus importantes :

{
"sap.app": {
"title": "{{appTitle}}",
"description": "{{appDescription}}"
},
"sap.ui5": {
"routing": {
"targets": {
"FlightBookList": {
"options": {
"settings": {
"initialLoad": true,
"variantManagement": "Page"
}
}
}
}
}
}
}

Générateur vs. Manuel : Aide à la décision

ScénarioGénérateurManuel
Nouveau projet GreenfieldRecommandéNon
App CRUD standardRecommandéNon
Hiérarchies complexesPartiellementAdaptation nécessaire
Migration depuis LegacyNonOui, pour le contrôle
Scénario UnmanagedLimitéGénéralement manuel
Apprentissage/FormationNonOui, pour la compréhension
PrototypageRecommandéNon

Quand utiliser le générateur ?

Recommandé :

  • Nouvelles applications standard
  • Scénario Managed avec Draft
  • Prototypes rapides
  • Conventions de nommage cohérentes importantes

Préférer manuel :

  • Unmanaged avec intégration Legacy
  • Hiérarchies BO complexes
  • Exigences spéciales de structure
  • Projets d’apprentissage pour comprendre RAP

Adaptations typiques après génération

Checklist pour objets générés

Adapter après génération :
□ Interface View
□ @EndUserText.label pour tous les champs
□ Associations vers autres Entities
□ @ObjectModel.text pour champs texte
□ Projection View
□ Définir @UI.headerInfo
□ @UI.lineItem pour List Report
□ @UI.identification pour Object Page
□ @UI.selectionField pour filtres
□ Behavior Definition
□ Ajouter validations
□ Determinations pour valeurs par défaut
□ Définir Custom Actions
□ Configurer contrôles d'autorisation
□ Service Binding
□ Activer Publish
□ Tester Preview dans le navigateur

Bonnes pratiques

1. Générer, puis adapter

Utilisez le générateur comme point de départ - pas comme produit fini :

Générateur → Squelette → Adaptation → Tests → Raffinement

2. Établir les conventions de nommage avant

Avant de générer, définissez les préfixes :

Z = Namespace client
I_ = Couche Interface
C_ = Couche Consumption
A_ = Abstract Entity
UI_ = Service UI
_O4 = OData V4

3. Générateur pour cohérence

Même pour développement manuel : Utilisez le générateur une fois pour voir la structure attendue - puis vous pouvez reconstruire de manière cohérente.

4. Utiliser le contrôle de version

Committer directement après chaque génération - pour pouvoir suivre les modifications :

Terminal window
# Après génération
git add .
git commit -m "feat: generated RAP BO for FlightBooking"
# Après adaptations
git commit -m "feat: added validations and UI annotations"

Conclusion

Les générateurs RAP économisent considérablement de temps lors de la création d’applications standard. La clé est dans l’utilisation correcte :

  1. Générateur pour le squelette - Structure et boilerplate
  2. Adaptation manuelle - Logique métier et finitions UI
  3. Approche itérative - Générer, tester, adapter

Pour les débutants, il est quand même recommandé de créer tous les objets manuellement une fois - pour comprendre ce que fait le générateur en arrière-plan. Ensuite, vous pouvez utiliser efficacement les générateurs.

Articles connexes