Reading and Creating Long Texts using RAP APIs

Reading and Creating Long Texts associated to any Application Objects Like Sales Order, Purchase Order are frequently required either to be displayed in a Fiori application or to transfer the data to an external systems via RAP API .

How to handle such scenarios with RAP( Restful ABAP Programming Model ) based APIs or using the Fiori Programming Model ( BOPF ) ?

Reading the Long text Using Virtual Elements:

Virtual elements are used if these elements are not provided as part of the original persistence data model but can be calculated using ABAP resources during runtime


Virtual Elements

Use the below syntax for the annotation of the virtual Elements:

define view <CdsConsumptionView>

as select from <data_source>


@ObjectModel.readOnly: true


@ObjectModel.virtualElementCalculatedBy: ‘ABAP:<code_exit_class>’

cast( ” as <dtype> preserving type) as <view.element>


As shown in the below code the virtual elements and also the Code exit class can be implemented in order to display the long text .

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Create RAP based Dispute cases'
define root view entity ZFCSM_DISPUTE_RAP_Root as select from R_DisputeCase { key DisputeCaseUUID, DisputeCaseCoordinator, DisputeCaseRootCause, CaseProcessingDeadlineDate, OriginalAmount, DisputedAmount, PaidAmount, CreditedAmount, WriteOffAmount, ManuallyClearedAmount, DisputeCaseCurrency, ContactPersonName, ContactPersonEmailAddress, ContactPersonPhoneNumber, ContactPersonFaxNumber, ContactPersonFaxCountry, ContactPerson, Customer, CompanyCode, DisputeCaseExternalApplication, CaseType, CaseID, CaseExternalReference, CaseCreatedBy, CaseCreatedOn, CaseLastChangedBy, CaseLastChangedOn, CaseClosedBy, CaseClosedTime, CasePlannedCloseDate, CaseProcessor, CaseResponsible, CaseTitle, CaseEscalationReason, CaseCategory, CasePriority, CaseAuthorizationLevel, CaseStatusProfile, CaseStatus, CaseSystemStatus, CaseReason, /* Associations */ _AuthLevel, _CaseAttribute, _CaseCategory, _CaseSystemStatus, _CaseTypes, _ChangedByContactCard, _ClosedByContactCard, _CompanyCode, _Country, _CreatedByContactCard, _Customer, _DisputeCaseCoordinatorCard, _DisputeCaseExternalAppl, _Escalation, _Individual, _Priority, _ProcessorContactCard, _Reasons, _ResponsibleContactCard, _RootCause, _StatProfile, @ObjectModel.virtualElement: true @ObjectModel.virtualElementCalculatedBy: 'ZCL_DISPUTE_NOTES' cast(' ' as abap.char( 1333 ) ) as note

Implementation of the CDS exit class

class ZCL_DISPUTE_NOTES definition public final create public . public section. interfaces IF_SADL_EXIT . interfaces IF_SADL_EXIT_CALC_ELEMENT_READ .
protected section.
private section.
ENDCLASS. CLASS ZCL_DISPUTE_NOTES IMPLEMENTATION. METHOD if_sadl_exit_calc_element_read~calculate. LOOP AT it_original_data ASSIGNING FIELD-SYMBOL(<ls_original>). TRY. DATA(lv_index) = sy-tabix. ASSIGN COMPONENT 'DisputeCaseUUID' OF STRUCTURE <ls_original> TO FIELD-SYMBOL(<lv_disputecaseuuid>).
* Check if note types are requested IF line_exists( it_requested_calc_elements[ table_line = 'NOTE' ] ).
* Get field ASSIGN COMPONENT 'NOTE' OF STRUCTURE ct_calculated_data[ lv_index ] TO FIELD-SYMBOL(<lv_note>). IF sy-subrc EQ 0. DATA : lt_case_note TYPE fdmo_t_case_note_md. DATA(lo_pr_backend) = cl_fdmo_proc_rec_bl=>get_instance( ). CHECK lo_pr_backend IS BOUND. lo_pr_backend->get_case_notes( EXPORTING iv_case_guid = <lv_disputecaseuuid> im_db_read = abap_true IMPORTING et_note = lt_case_note ). ENDIF. ENDIF. LOOP AT lt_case_note ASSIGNING FIELD-SYMBOL(<fs_case_note>). <lv_note> = | { <lv_note> } { <fs_case_note>-HEADER_LINE } { <fs_case_note>-content }| . ENDLOOP. CATCH cx_sy_itab_line_not_found INTO DATA(lo_x). RAISE EXCEPTION TYPE lx_sadl_exit EXPORTING previous = lo_x. ENDTRY. ENDLOOP. ENDMETHOD. METHOD IF_SADL_EXIT_CALC_ELEMENT_READ~GET_CALCULATION_INFO. LOOP AT it_requested_calc_elements REFERENCE INTO DATA(lo_req_calc_elem). CASE lo_req_calc_elem->*. WHEN 'note'. IF NOT line_exists( et_requested_orig_elements[ table_line = 'note' ] ). APPEND 'note' to et_requested_orig_elements. ENDIF. WHEN OTHERS. ENDCASE. ENDLOOP. ENDMETHOD.

Once you click on the UI Preview in the Service Binding ,below Fiori app will be displayed .


Service Binding UI Preview

Limitations of using Virtual Elements:

  • Only 1333 character length can be shown .In case of the Notes more than 1333 cannot be printed using the Virtual Elements.
  • Will work fine for 1:1 Relationship between object ID and the Note .However 1:N relationship does not work fine
  • Virtual elements cannot be used together with the grouping or the aggregation function.

CRUD Operations Using the BOPF based Long Text Framework :

  1. CRUD Operations Using the BOPF based Long Text Framework in case of 1:N Relationship of the note :
  • We can utilize the BOPF based CDS View directly in the Fiori Application by calling a new Odata service from the Manifest.Json file in the BSP application and correspondingly writing the Annotations for the same.



  • Use the Odata Service SGBT_NTE_CDS_API_D_SRV which in turn calls the below BOPF enabled CDS viewAPI%20for%20the%20Noteswhich in turn calls the SAP table sgbt_nte_cont where the notes information is stored

Limitations of using BOPF based CDS API :

  • This is not coupled together with the RAP framework as this follows the BOPF framework so this is not tightly integrated with the RAP API

RAP Integrated with the BOPF Object:

  • Use the Unmanaged query using the RAP query class as shown below for the display of the Long text :Unmanaged%20RAP%20Query
  • For the Update of the Long text implement the behavior definition in the save method use the below standard class to perform the CUD operations :


Class for the CUD Operations

Thus we can integrate both the long text BOPF based API into RAP architecture .

Please provide your valuable feedback if there are other ways to implement the same in RAP