Die Integration von Office 365 E-Mail in SAP BTP ABAP Environment ermöglicht den Versand von E-Mails direkt aus ABAP-Anwendungen über die Microsoft Graph API. In diesem Artikel zeigen wir die komplette Einrichtung von der Azure-Konfiguration bis zum funktionierenden ABAP-Code.
Architektur-Übersicht
┌──────────────────────────────────────────────────────────────────────────┐│ Office 365 Mail-Integration Architektur │├──────────────────────────────────────────────────────────────────────────┤│ ││ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ││ │ BTP ABAP │ │ Microsoft │ │ Office 365 │ ││ │ Environment │────>│ Entra ID │────>│ Mail Server │ ││ │ │ │ (Azure AD) │ │ │ ││ └─────────────────┘ └─────────────────┘ └─────────────────┘ ││ │ │ ││ │ │ ││ ▼ ▼ ││ ┌─────────────────┐ ┌─────────────────┐ ││ │ Communication │ │ OAuth 2.0 │ ││ │ Arrangement │ │ Access Token │ ││ └─────────────────┘ └─────────────────┘ ││ ││ Protokoll: HTTPS + OAuth 2.0 Client Credentials Flow ││ API: Microsoft Graph API (https://graph.microsoft.com) ││ │└──────────────────────────────────────────────────────────────────────────┘Voraussetzungen
| Komponente | Anforderung |
|---|---|
| Azure AD | Tenant mit Global Admin oder Application Admin Rechten |
| Office 365 | Lizenz mit Exchange Online (Business Basic oder höher) |
| BTP | ABAP Environment mit ADT-Zugang |
| Mailbox | Shared Mailbox oder Service Account für den Versand |
1. Azure AD App-Registrierung
Zuerst muss eine App-Registrierung in Microsoft Entra ID (ehemals Azure AD) angelegt werden.
Schritt 1: App registrieren
1. Azure Portal öffnen (portal.azure.com)2. Microsoft Entra ID → App registrations → New registration
Name: SAP-BTP-Mail-IntegrationSupported account types: Accounts in this organizational directory onlyRedirect URI: (leer lassen)
3. "Register" klickenSchritt 2: Client Secret erstellen
1. App öffnen → Certificates & secrets2. Client secrets → New client secret
Description: SAP BTP ABAP EnvironmentExpires: 24 months (empfohlen)
3. "Add" klicken4. Secret Value SOFORT kopieren und sicher speichern! (Wird nur einmal angezeigt)Schritt 3: API-Berechtigungen konfigurieren
Für den Mail-Versand über Microsoft Graph benötigen wir Application Permissions:
1. API permissions → Add a permission2. Microsoft Graph → Application permissions3. Folgende Berechtigungen hinzufügen:
☑ Mail.Send (E-Mails senden) ☑ Mail.ReadWrite (optional: Entwürfe erstellen) ☑ User.Read.All (optional: Benutzer-Info abrufen)
4. "Add permissions" klicken5. "Grant admin consent for [Tenant]" klickenWichtig: Application Permissions erfordern Admin Consent und erlauben den Versand als jeder Benutzer im Tenant.
Schritt 4: Wichtige IDs notieren
Nach der Registrierung benötigst du folgende Werte:
| Wert | Wo zu finden |
|---|---|
| Application (Client) ID | App Overview Seite |
| Directory (Tenant) ID | App Overview Seite |
| Client Secret | Certificates & secrets (bei Erstellung kopiert) |
Beispiel:
Application (Client) ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890Directory (Tenant) ID: 12345678-90ab-cdef-1234-567890abcdefClient Secret: Xyz123~AbCdEfGhIjKlMnOpQrStUvWx.YZ2. Communication Scenario in ABAP erstellen
Erstelle ein Custom Communication Scenario für die Microsoft Graph Integration.
Scenario-Definition
In ADT: Rechtsklick auf Package → New → Other ABAP Repository Object → Communication Scenario
<?xml version="1.0" encoding="utf-8"?><communicationScenario id="Z_MS_GRAPH_MAIL" scenarioType="customer"> <description>Microsoft Graph API - Mail Integration</description>
<outboundServices> <service id="Z_MS_GRAPH_API"> <description>Microsoft Graph REST API</description> <serviceType>http</serviceType> </service> </outboundServices>
<supportedAuthenticationMethods> <method>oauth2_client_credentials</method> </supportedAuthenticationMethods></communicationScenario>Nach dem Aktivieren ist das Scenario für die Administrator-Konfiguration verfügbar.
3. Communication Arrangement einrichten
Die Einrichtung erfolgt in den Fiori Apps des ABAP Environment.
Communication System anlegen
Fiori App: "Maintain Communication Systems"
System ID: MS_GRAPH_PRODSystem Name: Microsoft Graph API
General:├── Host Name: graph.microsoft.com├── Port: 443└── HTTPS: ☑
OAuth 2.0 Settings:├── Token Service URL Type: Dedicated├── Token Service URL: https://login.microsoftonline.com/{Tenant-ID}/oauth2/v2.0/token└── (Ersetze {Tenant-ID} mit deiner Directory/Tenant ID)Communication Arrangement anlegen
Fiori App: "Maintain Communication Arrangements"
Arrangement ID: Z_MS_GRAPH_MAIL_PRODScenario: Z_MS_GRAPH_MAILCommunication System: MS_GRAPH_PROD
Outbound Services:├── Z_MS_GRAPH_API: Active└── Path: /v1.0
Authentication Method: OAuth 2.0 Client Credentials├── Client ID: [Application (Client) ID aus Azure]├── Client Secret: [Secret aus Azure]└── Token Service Scope: https://graph.microsoft.com/.defaultWichtig: Der Scope https://graph.microsoft.com/.default ist erforderlich für Application Permissions.
4. ABAP-Implementierung
Jetzt implementieren wir die Klasse für den E-Mail-Versand über Microsoft Graph.
E-Mail-Versand Klasse
CLASS zcl_ms_graph_mail DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. INTERFACES if_oo_adt_classrun.
TYPES: BEGIN OF ty_email_address, address TYPE string, name TYPE string, END OF ty_email_address, tt_email_addresses TYPE STANDARD TABLE OF ty_email_address WITH EMPTY KEY.
TYPES: BEGIN OF ty_attachment, name TYPE string, content_type TYPE string, content TYPE xstring, END OF ty_attachment, tt_attachments TYPE STANDARD TABLE OF ty_attachment WITH EMPTY KEY.
METHODS send_mail IMPORTING iv_sender_mail TYPE string iv_subject TYPE string iv_body TYPE string iv_is_html TYPE abap_bool DEFAULT abap_false it_to TYPE tt_email_addresses it_cc TYPE tt_email_addresses OPTIONAL it_bcc TYPE tt_email_addresses OPTIONAL it_attachments TYPE tt_attachments OPTIONAL RAISING cx_http_dest_provider_error cx_web_http_client_error.
PRIVATE SECTION. CONSTANTS: c_scenario TYPE if_com_scenario_factory=>ty_cscn_id VALUE 'Z_MS_GRAPH_MAIL', c_service_id TYPE if_com_scenario_factory=>ty_cscn_outb_srv_id VALUE 'Z_MS_GRAPH_API'.
METHODS get_destination RETURNING VALUE(ro_destination) TYPE REF TO if_http_destination RAISING cx_http_dest_provider_error.
METHODS build_mail_json IMPORTING iv_subject TYPE string iv_body TYPE string iv_is_html TYPE abap_bool it_to TYPE tt_email_addresses it_cc TYPE tt_email_addresses it_bcc TYPE tt_email_addresses it_attachments TYPE tt_attachments RETURNING VALUE(rv_json) TYPE string.
METHODS build_recipients_json IMPORTING it_addresses TYPE tt_email_addresses RETURNING VALUE(rv_json) TYPE string.
METHODS build_attachments_json IMPORTING it_attachments TYPE tt_attachments RETURNING VALUE(rv_json) TYPE string.ENDCLASS.
CLASS zcl_ms_graph_mail IMPLEMENTATION. METHOD if_oo_adt_classrun~main. " Test-Mail versenden TRY. send_mail( iv_subject = 'Test aus SAP BTP' iv_body = |<html><body>| && |<h1>Willkommen</h1>| && |<p>Dies ist eine Test-E-Mail aus dem SAP BTP ABAP Environment.</p>| && |<p>Gesendet: { cl_abap_context_info=>get_system_date( ) }</p>| && |</body></html>| iv_is_html = abap_true name = 'Max Mustermann' ) ) ).
out->write( 'E-Mail erfolgreich gesendet!' ).
CATCH cx_http_dest_provider_error INTO DATA(lx_dest). out->write( |Destination-Fehler: { lx_dest->get_text( ) }| ). CATCH cx_web_http_client_error INTO DATA(lx_http). out->write( |HTTP-Fehler: { lx_http->get_text( ) }| ). ENDTRY. ENDMETHOD.
METHOD get_destination. ro_destination = cl_http_destination_provider=>create_by_comm_arrangement( comm_scenario = c_scenario service_id = c_service_id ). ENDMETHOD.
METHOD send_mail. " 1. Destination abrufen DATA(lo_destination) = get_destination( ).
" 2. HTTP-Client erstellen DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( i_destination = lo_destination ).
TRY. " 3. Request konfigurieren DATA(lo_request) = lo_client->get_http_request( ).
" Graph API Endpoint: /users/{user-id}/sendMail lo_request->set_uri_path( |/users/{ iv_sender_mail }/sendMail| ).
" 4. JSON-Body erstellen DATA(lv_json) = build_mail_json( iv_subject = iv_subject iv_body = iv_body iv_is_html = iv_is_html it_to = it_to it_cc = it_cc it_bcc = it_bcc it_attachments = it_attachments ).
lo_request->set_text( lv_json ). lo_request->set_header_field( i_name = 'Content-Type' i_value = 'application/json' ).
" 5. POST ausführen DATA(lo_response) = lo_client->execute( if_web_http_client=>post ). DATA(lv_status) = lo_response->get_status( )-code.
" 202 Accepted = Erfolgreich IF lv_status <> 202. DATA(lv_error) = lo_response->get_text( ). RAISE EXCEPTION TYPE cx_web_http_client_error EXPORTING text = |Mail-Versand fehlgeschlagen: { lv_status } - { lv_error }|. ENDIF.
CLEANUP. lo_client->close( ). ENDTRY. ENDMETHOD.
METHOD build_mail_json. " Microsoft Graph Mail JSON-Struktur erstellen DATA(lv_content_type) = COND string( WHEN iv_is_html = abap_true THEN 'HTML' ELSE 'Text' ).
rv_json = |\{| && | "message": \{| && | "subject": "{ escape( val = iv_subject format = cl_abap_format=>e_json_string ) }",| && | "body": \{| && | "contentType": "{ lv_content_type }",| && | "content": "{ escape( val = iv_body format = cl_abap_format=>e_json_string ) }"| && | \},| && | "toRecipients": { build_recipients_json( it_to ) }|.
" CC hinzufügen (falls vorhanden) IF it_cc IS NOT INITIAL. rv_json = rv_json && |,| && | "ccRecipients": { build_recipients_json( it_cc ) }|. ENDIF.
" BCC hinzufügen (falls vorhanden) IF it_bcc IS NOT INITIAL. rv_json = rv_json && |,| && | "bccRecipients": { build_recipients_json( it_bcc ) }|. ENDIF.
" Anhänge hinzufügen (falls vorhanden) IF it_attachments IS NOT INITIAL. rv_json = rv_json && |,| && | "attachments": { build_attachments_json( it_attachments ) }|. ENDIF.
rv_json = rv_json && | \},| && | "saveToSentItems": "true"| && |\}|. ENDMETHOD.
METHOD build_recipients_json. DATA: lt_json TYPE TABLE OF string.
LOOP AT it_addresses INTO DATA(ls_address). DATA(lv_entry) = |\{| && | "emailAddress": \{| && | "address": "{ ls_address-address }"|.
IF ls_address-name IS NOT INITIAL. lv_entry = lv_entry && |,| && | "name": "{ escape( val = ls_address-name format = cl_abap_format=>e_json_string ) }"|. ENDIF.
lv_entry = lv_entry && | \}| && |\}|.
APPEND lv_entry TO lt_json. ENDLOOP.
rv_json = |[{ concat_lines_of( table = lt_json sep = `, ` ) }]|. ENDMETHOD.
METHOD build_attachments_json. DATA: lt_json TYPE TABLE OF string.
LOOP AT it_attachments INTO DATA(ls_attachment). " Base64-Encoding des Inhalts DATA(lv_base64) = cl_web_http_utility=>encode_x_base64( ls_attachment-content ).
DATA(lv_entry) = |\{| && | "@odata.type": "#microsoft.graph.fileAttachment",| && | "name": "{ escape( val = ls_attachment-name format = cl_abap_format=>e_json_string ) }",| && | "contentType": "{ ls_attachment-content_type }",| && | "contentBytes": "{ lv_base64 }"| && |\}|.
APPEND lv_entry TO lt_json. ENDLOOP.
rv_json = |[{ concat_lines_of( table = lt_json sep = `, ` ) }]|. ENDMETHOD.ENDCLASS.5. Praktische Beispiele
Einfache Text-E-Mail
DATA(lo_mail) = NEW zcl_ms_graph_mail( ).
lo_mail->send_mail( iv_subject = 'Bestellung bestätigt' iv_body = |Sehr geehrter Kunde,\n\n| && |Ihre Bestellung wurde erfolgreich erfasst.\n\n| && |Mit freundlichen Grüßen\n| && |Ihr SAP-System| name = 'Max Mustermann' ) ) ).HTML-E-Mail mit Formatierung
DATA(lo_mail) = NEW zcl_ms_graph_mail( ).
DATA(lv_html) = |<html>| && |<head>| && | <style>| && | body \{ font-family: Arial, sans-serif; \}| && | h1 \{ color: #0070c0; \}| && | .highlight \{ background-color: #fff3cd; padding: 10px; \}| && | </style>| && |</head>| && |<body>| && | <h1>Buchungsbestätigung</h1>| && | <p>Sehr geehrter Herr Mustermann,</p>| && | <p>Ihre Flugbuchung wurde erfolgreich angelegt:</p>| && | <div class="highlight">| && | <strong>Buchungsnummer:</strong> FB-2026-001234<br>| && | <strong>Flug:</strong> LH 100<br>| && | <strong>Route:</strong> Frankfurt → New York<br>| && | <strong>Datum:</strong> 15.03.2026| && | </div>| && | <p>Mit freundlichen Grüßen,<br>Ihr Reisebüro</p>| && |</body>| && |</html>|.
lo_mail->send_mail( iv_subject = 'Ihre Buchungsbestätigung FB-2026-001234' iv_body = lv_html iv_is_html = abap_true name = 'Max Mustermann' ) )E-Mail mit Anhängen
DATA(lo_mail) = NEW zcl_ms_graph_mail( ).
" CSV-Daten als AnhangDATA(lv_csv) = |Buchungsnummer;Kunde;Betrag\n| && |FB-001;Müller;1250.00\n| && |FB-002;Schmidt;890.50\n| && |FB-003;Weber;2100.00|.
" String zu XString konvertierenDATA(lv_csv_xstring) = cl_abap_codepage=>convert_to( source = lv_csv codepage = 'UTF-8' ).
" PDF-Inhalt (z.B. aus RAP Action oder Adobe Forms)DATA: lv_pdf_xstring TYPE xstring." ... PDF generieren ...
lo_mail->send_mail( iv_subject = 'Monatlicher Buchungsbericht' iv_body = |<html><body>| && |<p>Anbei finden Sie den Buchungsbericht für Februar 2026.</p>| && |</body></html>| iv_is_html = abap_true name = 'Geschäftsleitung' ) ) it_attachments = VALUE #( ( name = 'buchungen_2026-02.csv' content_type = 'text/csv' content = lv_csv_xstring ) ( name = 'bericht_2026-02.pdf' content_type = 'application/pdf' content = lv_pdf_xstring ) ) ).E-Mail aus RAP Action versenden
METHOD send_booking_confirmation. " RAP Action: Buchungsbestätigung per E-Mail senden
READ ENTITIES OF zi_flightbook IN LOCAL MODE ENTITY FlightBook ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_bookings).
LOOP AT lt_bookings INTO DATA(ls_booking). " E-Mail-Adresse des Kunden ermitteln SELECT SINGLE email FROM zcustomer WHERE customer_id = @ls_booking-CustomerId INTO @DATA(lv_customer_email).
IF sy-subrc = 0 AND lv_customer_email IS NOT INITIAL. TRY. DATA(lo_mail) = NEW zcl_ms_graph_mail( ).
DATA(lv_body) = |<html><body>| && |<h2>Buchungsbestätigung</h2>| && |<p>Ihre Buchung wurde bestätigt:</p>| && |<ul>| && | <li><strong>Buchungsnr.:</strong> { ls_booking-BookingId }</li>| && | <li><strong>Flug:</strong> { ls_booking-FlightNumber }</li>| && | <li><strong>Datum:</strong> { ls_booking-FlightDate }</li>| && | <li><strong>Status:</strong> { ls_booking-Status }</li>| && |</ul>| && |</body></html>|.
lo_mail->send_mail( iv_subject = |Buchungsbestätigung { ls_booking-BookingId }| iv_body = lv_body iv_is_html = abap_true it_to = VALUE #( ( address = lv_customer_email ) ) ).
" Erfolgsmeldung APPEND VALUE #( %tky = ls_booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-success text = |E-Mail an { lv_customer_email } gesendet| ) ) TO reported-flightbook.
CATCH cx_root INTO DATA(lx_error). " Fehlermeldung APPEND VALUE #( %tky = ls_booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = |Mail-Fehler: { lx_error->get_text( ) }| ) ) TO reported-flightbook. ENDTRY. ENDIF. ENDLOOP.ENDMETHOD.6. Fehlerbehandlung
Erweiterte Klasse mit Fehlerbehandlung
CLASS zcl_ms_graph_mail_ext DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_mail_result, success TYPE abap_bool, message TYPE string, error_code TYPE string, END OF ty_mail_result.
METHODS send_mail_safe IMPORTING iv_sender_mail TYPE string iv_subject TYPE string iv_body TYPE string iv_is_html TYPE abap_bool DEFAULT abap_false it_to TYPE zcl_ms_graph_mail=>tt_email_addresses RETURNING VALUE(rs_result) TYPE ty_mail_result.
PRIVATE SECTION. METHODS parse_graph_error IMPORTING iv_json TYPE string RETURNING VALUE(rv_error) TYPE string.ENDCLASS.
CLASS zcl_ms_graph_mail_ext IMPLEMENTATION. METHOD send_mail_safe. TRY. DATA(lo_mail) = NEW zcl_ms_graph_mail( ).
lo_mail->send_mail( iv_sender_mail = iv_sender_mail iv_subject = iv_subject iv_body = iv_body iv_is_html = iv_is_html it_to = it_to ).
rs_result = VALUE #( success = abap_true message = 'E-Mail erfolgreich gesendet' ).
CATCH cx_http_dest_provider_error INTO DATA(lx_dest). rs_result = VALUE #( success = abap_false message = lx_dest->get_text( ) error_code = 'DESTINATION_ERROR' ).
CATCH cx_web_http_client_error INTO DATA(lx_http). rs_result = VALUE #( success = abap_false message = lx_http->get_text( ) error_code = 'HTTP_ERROR' ). ENDTRY. ENDMETHOD.
METHOD parse_graph_error. " Microsoft Graph Fehler-JSON parsen " Beispiel: {"error":{"code":"InvalidAuthenticationToken","message":"..."}} TRY. DATA: BEGIN OF ls_error, BEGIN OF error, code TYPE string, message TYPE string, END OF error, END OF ls_error.
/ui2/cl_json=>deserialize( EXPORTING json = iv_json CHANGING data = ls_error ).
rv_error = |{ ls_error-error-code }: { ls_error-error-message }|.
CATCH cx_root. rv_error = iv_json. ENDTRY. ENDMETHOD.ENDCLASS.Häufige Fehler und Lösungen
| Fehlercode | Beschreibung | Lösung |
|---|---|---|
| 401 Unauthorized | Token ungültig oder abgelaufen | Client Secret erneuern, Tenant-ID prüfen |
| 403 Forbidden | Keine Berechtigung | Admin Consent erteilen, Mail.Send Permission prüfen |
| 404 Not Found | Sender-Mailbox nicht gefunden | E-Mail-Adresse des Senders überprüfen |
| 400 Bad Request | Ungültiges JSON oder fehlende Felder | JSON-Struktur validieren |
| 429 Too Many Requests | Rate Limiting | Retry mit Exponential Backoff implementieren |
Rate Limiting beachten
Microsoft Graph hat Rate Limits. Für Mail-Versand:
Limit: 10.000 Anfragen pro 10 Minuten pro App 10.000 E-Mails pro Tag pro Mailbox
Best Practice:- Batch-Versand vermeiden- Bei 429: Retry-After Header beachten- Application Logging für Monitoring7. Shared Mailbox vs. Service Account
Für den produktiven Einsatz empfiehlt sich eine Shared Mailbox:
| Aspekt | Shared Mailbox | Service Account |
|---|---|---|
| Lizenz | Keine eigene Lizenz nötig | Benötigt Exchange-Lizenz |
| Kosten | Kostenfrei | Monatliche Kosten |
| Verwaltung | Über Exchange Admin Center | Wie normaler Benutzer |
| Empfehlung | Für automatische Mails | Nur wenn nötig |
Shared Mailbox einrichten
1. Microsoft 365 Admin Center → Teams & Groups → Shared Mailboxes2. "Add a shared mailbox" klicken3. Name: SAP-Notifications Email: [email protected]4. Mailbox erstellen5. In Azure AD: App-Permission Mail.Send erlaubt Versand über diese Mailbox8. Sicherheits-Best-Practices
| Thema | Empfehlung |
|---|---|
| Secret Rotation | Client Secret alle 6-12 Monate erneuern |
| Least Privilege | Nur Mail.Send Permission, keine Read-Rechte |
| Sender-Whitelist | Nur dedizierte Mailboxen als Sender erlauben |
| Logging | Alle Mail-Aktionen mit Application Logging protokollieren |
| Monitoring | Azure AD Sign-in Logs überwachen |
| Error Handling | Sensible Daten nicht in Fehlermeldungen ausgeben |
Application Logging integrieren
METHOD send_mail_with_logging. " Logging initialisieren DATA(lo_log) = cl_bali_log=>create_with_header( header = cl_bali_header_setter=>create( )->set_object( 'ZMS_GRAPH' ) ->set_subobject( 'MAIL' ) ).
TRY. DATA(lo_mail) = NEW zcl_ms_graph_mail( ). lo_mail->send_mail( iv_sender_mail = iv_sender iv_subject = iv_subject iv_body = iv_body it_to = it_recipients ).
" Erfolg loggen lo_log->add_item( cl_bali_message_setter=>create( severity = if_bali_constants=>c_severity_status id = 'ZMS_GRAPH' number = '001' )->set_text( |Mail an { it_recipients[ 1 ]-address } gesendet| ) ).
CATCH cx_root INTO DATA(lx_error). " Fehler loggen lo_log->add_item( cl_bali_message_setter=>create( severity = if_bali_constants=>c_severity_error id = 'ZMS_GRAPH' number = '002' )->set_text( |Fehler: { lx_error->get_text( ) }| ) ). ENDTRY.
" Log speichern cl_bali_log_db=>get_instance( )->save_log( lo_log ).ENDMETHOD.Fazit
Die Integration von Office 365 Mail in SAP BTP ABAP Environment bietet eine moderne Alternative zu klassischen Mail-Lösungen. Die Kombination aus Microsoft Graph API, OAuth 2.0 und dem Communication Management in ABAP Cloud ermöglicht sichere und gut wartbare E-Mail-Funktionalität.
Wichtige Punkte:
- Azure AD App-Registrierung mit Application Permissions (Mail.Send)
- Communication Scenario für saubere Trennung von Entwicklung und Konfiguration
- OAuth 2.0 Client Credentials für Machine-to-Machine-Authentifizierung
- Shared Mailbox als kostengünstige Sender-Lösung
- Error Handling und Logging für produktiven Betrieb
Weiterführende Artikel
- Communication Scenarios Guide - Umfassender Guide zu Communication Management
- HTTP Client in ABAP - REST-APIs aufrufen
- Application Logging - Logging in ABAP Cloud
- OAuth JWT in ABAP Cloud - Token-basierte Authentifizierung