Attachment Handling ist ein zentrales Thema in modernen Geschäftsanwendungen. Ob Rechnungsbelege, Verträge oder technische Zeichnungen – Benutzer erwarten, dass sie Dokumente direkt in der Anwendung hochladen, speichern und wieder herunterladen können. In ABAP Cloud und RAP gibt es mehrere Ansätze, um diese Anforderung umzusetzen.
Grundlegende Konzepte
In ABAP Cloud stehen verschiedene Methoden für das Attachment Handling zur Verfügung:
| Ansatz | Beschreibung | Anwendungsfall |
|---|---|---|
| LOB-Felder in CDS | Large Objects direkt in der Datenbank | Kleine bis mittlere Dateien |
| Attachment Service (GOS) | SAP Standard-Service für Anhänge | Integration mit SAP-Standardobjekten |
| External Storage | Externe Speicherdienste (Object Store) | Große Dateien, Compliance |
| Custom Implementation | Eigene Tabellen und Logik | Maximale Flexibilität |
Architektur-Übersicht
┌─────────────────────────────────────────────────────────────────────────────┐│ Attachment Handling in RAP ││ ││ ┌────────────────────────────────────────────────────────────────────────┐ ││ │ Fiori Elements UI │ ││ │ ┌─────────────────────┐ ┌─────────────────────┐ │ ││ │ │ Upload Control │ │ Download Action │ │ ││ │ │ (Drag & Drop) │ │ (Button/Link) │ │ ││ │ └──────────┬──────────┘ └──────────┬──────────┘ │ ││ └─────────────┼────────────────────────┼──────────────────────────────────┘ ││ │ │ ││ ▼ ▼ ││ ┌────────────────────────────────────────────────────────────────────────┐ ││ │ RAP Business Object │ ││ │ ┌─────────────────────┐ ┌─────────────────────┐ │ ││ │ │ LOB-Feld │ │ RAP Actions │ │ ││ │ │ (Attachment) │ │ upload/download │ │ ││ │ └──────────┬──────────┘ └──────────┬──────────┘ │ ││ └─────────────┼────────────────────────┼──────────────────────────────────┘ ││ │ │ ││ ▼ ▼ ││ ┌────────────────────────────────────────────────────────────────────────┐ ││ │ Speicheroptionen │ ││ │ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ │ ││ │ │ HANA LOB │ │ Object Store │ │ DMS │ │ ││ │ │ (Datenbank) │ │ (Cloud) │ │ (Optional) │ │ ││ │ └───────────────────┘ └───────────────────┘ └───────────────────┘ │ ││ └────────────────────────────────────────────────────────────────────────┘ │└─────────────────────────────────────────────────────────────────────────────┘LOB-Handling in CDS Views
Der einfachste Ansatz für Attachments ist die Verwendung von Large Object (LOB) Feldern direkt in der Datenbanktabelle. CDS Views unterstützen LOB-Felder für binäre Daten.
Datenbanktabelle mit LOB-Feld
@EndUserText.label : 'Dokument mit Attachment'@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE@AbapCatalog.tableCategory : #TRANSPARENT@AbapCatalog.deliveryClass : #A@AbapCatalog.dataMaintenance : #RESTRICTEDdefine table zdocument { key client : abap.clnt not null; key document_uuid : sysuuid_x16 not null; document_id : abap.numc(10); document_name : abap.char(100); description : abap.char(255);
// LOB-Felder für Attachment @AbapCatalog.typeUsage : #OPEN attachment : abap.rawstring(0);
mime_type : abap.char(128); file_name : abap.char(255); file_size : abap.int4;
created_by : abap.uname; created_at : timestampl; last_changed_by : abap.uname; last_changed_at : timestampl;}Wichtige Hinweise zu LOB-Feldern:
abap.rawstring(0)definiert ein BLOB (Binary Large Object) ohne Längenbeschränkungabap.string(0)wäre ein CLOB für Textdaten- LOB-Felder werden in HANA effizient gespeichert (nicht im Row Store)
- Maximale Größe: bis zu 2 GB pro Feld
CDS View mit LOB-Feld
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Dokument mit Attachment'define root view entity ZI_Document as select from zdocument{ key document_uuid as DocumentUUID, document_id as DocumentID, document_name as DocumentName, description as Description,
// LOB-Feld exponieren @Semantics.largeObject: { mimeType: 'MimeType', fileName: 'FileName', contentDispositionPreference: #ATTACHMENT } attachment as Attachment,
mime_type as MimeType, file_name as FileName, file_size as FileSize,
@Semantics.user.createdBy: true created_by as CreatedBy, @Semantics.systemDateTime.createdAt: true created_at as CreatedAt, @Semantics.user.lastChangedBy: true last_changed_by as LastChangedBy, @Semantics.systemDateTime.lastChangedAt: true last_changed_at as LastChangedAt}Die Annotation @Semantics.largeObject ist entscheidend:
| Parameter | Beschreibung |
|---|---|
mimeType | Verweis auf Feld mit MIME-Type (z.B. application/pdf) |
fileName | Verweis auf Feld mit Dateinamen |
contentDispositionPreference | #ATTACHMENT für Download, #INLINE für Anzeige |
Upload und Download in Fiori Elements
Fiori Elements unterstützt LOB-Felder automatisch mit Upload- und Download-Funktionalität.
Projection View mit UI-Annotationen
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Dokument Projection'@Metadata.allowExtensions: truedefine root view entity ZC_Document provider contract transactional_query as projection on ZI_Document{ key DocumentUUID, DocumentID, DocumentName, Description,
// LOB-Feld für UI Attachment, MimeType, FileName, FileSize,
CreatedBy, CreatedAt, LastChangedBy, LastChangedAt}Metadata Extension für Upload-UI
@Metadata.layer: #COREannotate view ZC_Document with{ @UI.facet: [ { id: 'GeneralInfo', type: #IDENTIFICATION_REFERENCE, label: 'Allgemeine Informationen', position: 10 }, { id: 'AttachmentFacet', type: #FIELDGROUP_REFERENCE, targetQualifier: 'Attachment', label: 'Anhang', position: 20 } ]
@UI.lineItem: [{ position: 10, importance: #HIGH }] @UI.identification: [{ position: 10 }] DocumentID;
@UI.lineItem: [{ position: 20, importance: #HIGH }] @UI.identification: [{ position: 20 }] DocumentName;
@UI.identification: [{ position: 30 }] Description;
// Attachment-Felder @UI.fieldGroup: [{ qualifier: 'Attachment', position: 10, label: 'Datei' }] Attachment;
@UI.fieldGroup: [{ qualifier: 'Attachment', position: 20, label: 'Dateityp' }] @UI.hidden: true MimeType;
@UI.fieldGroup: [{ qualifier: 'Attachment', position: 30, label: 'Dateiname' }] FileName;
@UI.fieldGroup: [{ qualifier: 'Attachment', position: 40, label: 'Größe (Bytes)' }] FileSize;}Behavior Definition für LOB-Handling
managed implementation in class zbp_i_document unique;strict ( 2 );
define behavior for ZI_Document alias Documentpersistent table zdocumentlock masterauthorization master ( instance ){ field ( readonly ) DocumentUUID, CreatedBy, CreatedAt, LastChangedBy, LastChangedAt; field ( readonly ) FileSize; field ( mandatory ) DocumentName;
create; update; delete;
// Determination für FileSize-Berechnung determination calculateFileSize on modify { field Attachment; }
mapping for zdocument { DocumentUUID = document_uuid; DocumentID = document_id; DocumentName = document_name; Description = description; Attachment = attachment; MimeType = mime_type; FileName = file_name; FileSize = file_size; CreatedBy = created_by; CreatedAt = created_at; LastChangedBy = last_changed_by; LastChangedAt = last_changed_at; }}Behavior Implementation
CLASS lhc_document DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS calculatefilesize FOR DETERMINE ON MODIFY IMPORTING keys FOR document~calculatefilesize.ENDCLASS.
CLASS lhc_document IMPLEMENTATION. METHOD calculatefilesize. " Dokumente mit geänderten Attachments lesen READ ENTITIES OF zi_document IN LOCAL MODE ENTITY document FIELDS ( attachment ) WITH CORRESPONDING #( keys ) RESULT DATA(documents).
" FileSize für jedes Dokument berechnen LOOP AT documents ASSIGNING FIELD-SYMBOL(<doc>). DATA(lv_size) = xstrlen( <doc>-attachment ).
MODIFY ENTITIES OF zi_document IN LOCAL MODE ENTITY document UPDATE FIELDS ( filesize ) WITH VALUE #( ( %tky = <doc>-%tky filesize = lv_size ) ) FAILED DATA(failed) REPORTED DATA(reported). ENDLOOP. ENDMETHOD.ENDCLASS.Custom Upload/Download Actions
Für mehr Kontrolle über den Upload- und Download-Prozess können eigene RAP Actions implementiert werden.
Behavior Definition mit Actions
managed implementation in class zbp_i_document unique;strict ( 2 );
define behavior for ZI_Document alias Documentpersistent table zdocumentlock masterauthorization master ( instance ){ // ... Standard-Operationen ...
// Upload Action mit Parameter action uploadAttachment parameter ZD_AttachmentUpload result [1] $self;
// Download Action action downloadAttachment result [1] ZD_AttachmentDownload;
// Attachment löschen action deleteAttachment result [1] $self;}Abstract Entity für Upload-Parameter
@EndUserText.label: 'Attachment Upload Parameter'define abstract entity ZD_AttachmentUpload{ @Semantics.largeObject: { mimeType: 'MimeType', fileName: 'FileName', contentDispositionPreference: #ATTACHMENT } Content : abap.rawstring(0); MimeType : abap.char(128); FileName : abap.char(255);}Abstract Entity für Download-Result
@EndUserText.label: 'Attachment Download Result'define abstract entity ZD_AttachmentDownload{ @Semantics.largeObject: { mimeType: 'MimeType', fileName: 'FileName', contentDispositionPreference: #ATTACHMENT } Content : abap.rawstring(0); MimeType : abap.char(128); FileName : abap.char(255); FileSize : abap.int4;}Action Implementation
CLASS lhc_document DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS uploadattachment FOR MODIFY IMPORTING keys FOR ACTION document~uploadattachment RESULT result.
METHODS downloadattachment FOR READ IMPORTING keys FOR ACTION document~downloadattachment RESULT result.
METHODS deleteattachment FOR MODIFY IMPORTING keys FOR ACTION document~deleteattachment RESULT result.ENDCLASS.
CLASS lhc_document IMPLEMENTATION. METHOD uploadattachment. " Validierung LOOP AT keys ASSIGNING FIELD-SYMBOL(<key>). IF <key>-%param-content IS INITIAL. APPEND VALUE #( %tky = <key>-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Bitte wählen Sie eine Datei aus' ) ) TO reported-document. APPEND VALUE #( %tky = <key>-%tky ) TO failed-document. CONTINUE. ENDIF.
" Dateigröße prüfen (max 10 MB) DATA(lv_size) = xstrlen( <key>-%param-content ). IF lv_size > 10485760. " 10 MB APPEND VALUE #( %tky = <key>-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Datei zu groß (max. 10 MB)' ) ) TO reported-document. APPEND VALUE #( %tky = <key>-%tky ) TO failed-document. CONTINUE. ENDIF.
" MIME-Type validieren DATA(lv_allowed) = abap_false. CASE <key>-%param-mimetype. WHEN 'application/pdf' OR 'image/jpeg' OR 'image/png' OR 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' OR 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'. lv_allowed = abap_true. ENDCASE.
IF lv_allowed = abap_false. APPEND VALUE #( %tky = <key>-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Dateityp nicht erlaubt' ) ) TO reported-document. APPEND VALUE #( %tky = <key>-%tky ) TO failed-document. CONTINUE. ENDIF.
" Attachment speichern MODIFY ENTITIES OF zi_document IN LOCAL MODE ENTITY document UPDATE FIELDS ( attachment mimetype filename filesize ) WITH VALUE #( ( %tky = <key>-%tky attachment = <key>-%param-content mimetype = <key>-%param-mimetype filename = <key>-%param-filename filesize = lv_size ) ) FAILED DATA(update_failed) REPORTED DATA(update_reported).
IF update_failed IS NOT INITIAL. APPEND LINES OF update_failed-document TO failed-document. APPEND LINES OF update_reported-document TO reported-document. ELSE. " Erfolg: Geänderte Entität zurückgeben READ ENTITIES OF zi_document IN LOCAL MODE ENTITY document ALL FIELDS WITH VALUE #( ( %tky = <key>-%tky ) ) RESULT DATA(documents).
result = VALUE #( FOR doc IN documents ( %tky = doc-%tky %param = doc ) ). ENDIF. ENDLOOP. ENDMETHOD.
METHOD downloadattachment. " Dokument mit Attachment lesen READ ENTITIES OF zi_document IN LOCAL MODE ENTITY document FIELDS ( attachment mimetype filename filesize ) WITH CORRESPONDING #( keys ) RESULT DATA(documents) FAILED failed.
" Download-Result aufbauen LOOP AT documents ASSIGNING FIELD-SYMBOL(<doc>). IF <doc>-attachment IS INITIAL. APPEND VALUE #( %tky = <doc>-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-warning text = 'Kein Attachment vorhanden' ) ) TO reported-document. CONTINUE. ENDIF.
APPEND VALUE #( %tky = <doc>-%tky %param = VALUE #( content = <doc>-attachment mimetype = <doc>-mimetype filename = <doc>-filename filesize = <doc>-filesize ) ) TO result. ENDLOOP. ENDMETHOD.
METHOD deleteattachment. " Attachment-Felder leeren MODIFY ENTITIES OF zi_document IN LOCAL MODE ENTITY document UPDATE FIELDS ( attachment mimetype filename filesize ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky attachment = VALUE #( ) mimetype = '' filename = '' filesize = 0 ) ) FAILED failed REPORTED reported.
IF failed IS INITIAL. " Geänderte Entitäten zurückgeben READ ENTITIES OF zi_document IN LOCAL MODE ENTITY document ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(documents).
result = VALUE #( FOR doc IN documents ( %tky = doc-%tky %param = doc ) ). ENDIF. ENDMETHOD.ENDCLASS.Multiple Attachments pro Entity
Wenn ein Business Object mehrere Anhänge unterstützen soll, wird eine separate Child-Entity für Attachments verwendet.
Attachment Child Entity
@EndUserText.label : 'Document Attachments'define table zdoc_attachment { key client : abap.clnt not null; key attachment_uuid : sysuuid_x16 not null; parent_uuid : sysuuid_x16 not null; attachment_name : abap.char(100);
@AbapCatalog.typeUsage : #OPEN content : abap.rawstring(0);
mime_type : abap.char(128); file_name : abap.char(255); file_size : abap.int4;
created_by : abap.uname; created_at : timestampl;}CDS View mit Composition
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Dokument'define root view entity ZI_DocumentWithAtt as select from zdocument composition [0..*] of ZI_DocumentAttachment as _Attachments{ key document_uuid as DocumentUUID, document_id as DocumentID, document_name as DocumentName, description as Description,
// Association zu Attachments _Attachments}
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Dokument Attachment'define view entity ZI_DocumentAttachment as select from zdoc_attachment association to parent ZI_DocumentWithAtt as _Document on $projection.ParentUUID = _Document.DocumentUUID{ key attachment_uuid as AttachmentUUID, parent_uuid as ParentUUID, attachment_name as AttachmentName,
@Semantics.largeObject: { mimeType: 'MimeType', fileName: 'FileName', contentDispositionPreference: #ATTACHMENT } content as Content,
mime_type as MimeType, file_name as FileName, file_size as FileSize,
@Semantics.user.createdBy: true created_by as CreatedBy, @Semantics.systemDateTime.createdAt: true created_at as CreatedAt,
_Document}Behavior Definition für Parent-Child
managed implementation in class zbp_i_documentwithatt unique;strict ( 2 );
define behavior for ZI_DocumentWithAtt alias Documentpersistent table zdocumentlock masterauthorization master ( instance ){ create; update; delete;
association _Attachments { create; }
mapping for zdocument { DocumentUUID = document_uuid; DocumentID = document_id; DocumentName = document_name; Description = description; }}
define behavior for ZI_DocumentAttachment alias Attachmentpersistent table zdoc_attachmentlock dependent by _Documentauthorization dependent by _Document{ field ( readonly ) AttachmentUUID, ParentUUID, CreatedBy, CreatedAt; field ( readonly ) FileSize;
update; delete;
determination calculateSize on modify { field Content; }
mapping for zdoc_attachment { AttachmentUUID = attachment_uuid; ParentUUID = parent_uuid; AttachmentName = attachment_name; Content = content; MimeType = mime_type; FileName = file_name; FileSize = file_size; CreatedBy = created_by; CreatedAt = created_at; }}Speicheroptionen und Limits
Datenbank-Limits
| Datenbank | Max. LOB-Größe | Empfehlung |
|---|---|---|
| SAP HANA | 2 GB | Bis 100 MB direkt in DB |
| MaxDB | 2 GB | Bis 100 MB direkt in DB |
Alternativen für große Dateien
Für Dateien über 100 MB oder bei hohem Speicherbedarf empfehlen sich externe Speicherlösungen:
- SAP Object Store Service auf BTP
- Azure Blob Storage / AWS S3 via Destination
- SAP Document Management Service
Integration mit Object Store
CLASS zcl_object_store_client DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_object_metadata, object_key TYPE string, bucket TYPE string, content_type TYPE string, size TYPE i, END OF ty_object_metadata.
METHODS upload_object IMPORTING iv_bucket TYPE string iv_object_key TYPE string iv_content TYPE xstring iv_content_type TYPE string RETURNING VALUE(rs_metadata) TYPE ty_object_metadata RAISING cx_http_dest_provider_error cx_web_http_client_error.
METHODS download_object IMPORTING iv_bucket TYPE string iv_object_key TYPE string RETURNING VALUE(rv_content) TYPE xstring RAISING cx_http_dest_provider_error cx_web_http_client_error.
METHODS delete_object IMPORTING iv_bucket TYPE string iv_object_key TYPE string RAISING cx_http_dest_provider_error cx_web_http_client_error.
ENDCLASS.
CLASS zcl_object_store_client IMPLEMENTATION. METHOD upload_object. " HTTP-Destination für Object Store DATA(lo_dest) = cl_http_destination_provider=>create_by_cloud_destination( i_name = 'OBJECT_STORE' i_service_instance_name = 'object-store-instance' ).
DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( lo_dest ).
" Request vorbereiten DATA(lo_request) = lo_client->get_http_request( ). lo_request->set_uri_path( |/{ iv_bucket }/{ iv_object_key }| ). lo_request->set_header_field( i_name = 'Content-Type' i_value = iv_content_type ). lo_request->set_binary_body( iv_content ).
" Upload ausführen (PUT) DATA(lo_response) = lo_client->execute( if_web_http_client=>put ).
IF lo_response->get_status( )-code <> 200 AND lo_response->get_status( )-code <> 201. RAISE EXCEPTION TYPE cx_web_http_client_error. ENDIF.
" Metadata zurückgeben rs_metadata = VALUE #( object_key = iv_object_key bucket = iv_bucket content_type = iv_content_type size = xstrlen( iv_content ) ).
lo_client->close( ). ENDMETHOD.
METHOD download_object. DATA(lo_dest) = cl_http_destination_provider=>create_by_cloud_destination( i_name = 'OBJECT_STORE' i_service_instance_name = 'object-store-instance' ).
DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( lo_dest ).
DATA(lo_request) = lo_client->get_http_request( ). lo_request->set_uri_path( |/{ iv_bucket }/{ iv_object_key }| ).
" Download ausführen (GET) DATA(lo_response) = lo_client->execute( if_web_http_client=>get ).
IF lo_response->get_status( )-code <> 200. RAISE EXCEPTION TYPE cx_web_http_client_error. ENDIF.
rv_content = lo_response->get_binary( ).
lo_client->close( ). ENDMETHOD.
METHOD delete_object. DATA(lo_dest) = cl_http_destination_provider=>create_by_cloud_destination( i_name = 'OBJECT_STORE' i_service_instance_name = 'object-store-instance' ).
DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( lo_dest ).
DATA(lo_request) = lo_client->get_http_request( ). lo_request->set_uri_path( |/{ iv_bucket }/{ iv_object_key }| ).
" Delete ausführen DATA(lo_response) = lo_client->execute( if_web_http_client=>delete ).
IF lo_response->get_status( )-code <> 200 AND lo_response->get_status( )-code <> 204. RAISE EXCEPTION TYPE cx_web_http_client_error. ENDIF.
lo_client->close( ). ENDMETHOD.ENDCLASS.Best Practices
1. Validierung beim Upload
METHOD validate_attachment. " Dateigröße prüfen DATA(lv_max_size) = 10485760. " 10 MB IF xstrlen( iv_content ) > lv_max_size. RAISE EXCEPTION TYPE zcx_attachment_error EXPORTING textid = zcx_attachment_error=>file_too_large max_size = lv_max_size. ENDIF.
" MIME-Type prüfen DATA(lt_allowed_types) = VALUE string_table( ( `application/pdf` ) ( `image/jpeg` ) ( `image/png` ) ( `application/vnd.openxmlformats-officedocument.wordprocessingml.document` ) ( `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` ) ).
IF NOT line_exists( lt_allowed_types[ table_line = iv_mime_type ] ). RAISE EXCEPTION TYPE zcx_attachment_error EXPORTING textid = zcx_attachment_error=>mime_type_not_allowed mime_type = iv_mime_type. ENDIF.
" Virus-Scan (falls verfügbar) " cl_vscan_scanner=>scan( ... )ENDMETHOD.2. Performance-Optimierung
" Attachment-Content nur laden wenn benötigtREAD ENTITIES OF zi_document IN LOCAL MODE ENTITY document FIELDS ( documentname mimetype filename filesize ) " NICHT: attachment WITH CORRESPONDING #( keys ) RESULT DATA(document_list).
" Attachment separat laden für DownloadREAD ENTITIES OF zi_document IN LOCAL MODE ENTITY document FIELDS ( attachment ) WITH CORRESPONDING #( download_keys ) RESULT DATA(attachments).3. Sicherheit
- Berechtigung prüfen: Attachment-Download nur für berechtigte Benutzer
- Virus-Scan: Bei kritischen Anwendungen Dateien vor dem Speichern scannen
- Input-Validierung: Dateitypen und -größen strikt prüfen
- Verschlüsselung: Sensible Dokumente verschlüsselt speichern
Zusammenfassung
Attachment Handling in ABAP Cloud bietet flexible Optionen:
| Ansatz | Vorteile | Nachteile |
|---|---|---|
| LOB in Tabelle | Einfach, automatisches UI | Begrenzte Größe, DB-Last |
| Custom Actions | Volle Kontrolle, Validierung | Mehr Implementierungsaufwand |
| Child-Entity | Multiple Attachments | Komplexere Struktur |
| Object Store | Unbegrenzte Größe, performant | Externe Abhängigkeit |
Die Wahl hängt von den Anforderungen ab: Für einfache Dokumente bis 10 MB reichen LOB-Felder, für komplexe Szenarien mit vielen großen Dateien empfiehlt sich eine Kombination aus Metadaten in der DB und Content im Object Store.
Weiterführende Themen
- RAP Grundlagen - Business Object Entwicklung
- Dateioperationen in ABAP - Klassische Dateiverarbeitung
- HTTP-Client in ABAP Cloud - Externe Services anbinden
- RAP Actions und Functions - Eigene Operationen definieren