This is a test message to test the length of the message box.
Login
BTP Create Entity OData v4 with Draft
Erstellt von Software-Heroes

BTP - Create Entity für OData v4 mit Draft

175

In diesem Artikel geht es um den Flow zum Anlegen und Aktivieren einer Instanz in der BTP aus On-Premise, dabei ist der Endpunkt eine OData Version 4 der Draft unterstützt.

Werbung


In einem aktuellen Projekt möchten wir aus einem On-Premise System einen Endpunkt in der BTP (ABAP Environment) aufrufen, um eine neue Entität anzulegen. Dabei handelt es sich um einen OData der Version 4 und der Endpunkt arbeitet mit Draft. Es sind einige Aufrufe nötig, um einen neuen Eintrag in der Entität zu erzeugen und auch zu aktivieren, sodass er in der Anwendung sichtbar wird.

 

Einleitung

Um was geht es genau in diesem Artikel? Der OData Endpunkt ist eine RAP Anwendung, die eine API zur Verfügung stellt, um die Möglichkeit zu bieten neue Einträge auf dem ABAP Environment anzulegen. Events und den Event Mesh können wir hier nicht nutzen, da wir von der neuen Instanz die Identifikation benötigen, um sie der Anwendung On-Premise zur Verfügung zu stellen, wir benötigen daher eine synchrone Schnittstelle.

 

Flow

Bevor wir also in die Details des Prozesses gehen, hier schon einmal der gesamte Flow in einer Grafik zusammengefasst. Für mehr Details einfach die Grafik anklicken und heranzoomen. In den folgenden Abschnitten werden wir dann die verschiedenen Aufrufe durchführen und den entsprechenden Nutzen erklären.

 

 

Destination

Bevor wir allerdings Aufrufe durchführen können, benötigen wir eine Destination bzw. RFC-Verbindung in der SM59. Dafür benötigen wir unseren Endpunkt auf der BTP und Zugangsdaten in Form von Basic Authentification (User und Passwort) oder einen OAuth Endpunkt. In unserem Beispiel nutzen wir die Basic Authentification zum Anmelden an dem Endpunkt. Dazu legen wir eine Verbindung vom Typ "G" an, Ziel ist der Account des ABAP Environments "<SUBACCOUNT-ID>.abap.eu10.hana.ondemand.com", hier solltest du deine Adresse eintragen.

 

Unter Login & Sicherheit dann den User und das Passwort hinterlegen und im unteren Teil SSL aktivieren.

 

Vorbereitung

HTTP Client

Als erstes benötigen wir einen HTTP Client, um Abfragen durchführen zu können. Dazu legen wir einen Client auf Basis der angelegten Verbindung an und speichern uns die Instanz in einer Member-Variable der Klasse. Im Anschluss aktvieren wir noch die Annahme von Cookies, da wir noch einige Anfragen durchführen werden.

cl_http_client=>create_by_destination( EXPORTING destination = 'TEST_xxx'
                                       IMPORTING client      = mo_http_client ).
                                       
mo_http_client->propertytype_accept_cookie = if_http_client=>co_enabled.

 

Senden und Empfangen

Weiterhin verwenden wir eine Hilfsmethode zum Senden des Requests und dem Empfangen des Response, diese Methode werden wir in den folgenden Abschnitten immer wieder aufrufen und sparen uns somit etwas Coding.

METHOD process_send_and_receive.
  mo_http_client->send( EXCEPTIONS http_communication_failure = 1
                                   http_invalid_state         = 2
                                   http_processing_failed     = 3
                                   http_invalid_timeout       = 4
                                   OTHERS                     = 5 ).
  IF sy-subrc <> 0.
  ENDIF.

  mo_http_client->receive( EXCEPTIONS http_communication_failure = 1
                                      http_invalid_state         = 2
                                      http_processing_failed     = 3
                                      OTHERS                     = 4 ).
  IF sy-subrc <> 0.
  ENDIF.
ENDMETHOD.

 

Zusätzlich definieren wir in der Klasse eine Konstante, die den Grundpfad zum OData Endpunkt enthält, am Ende sollte der Slash stehen.

CONSTANTS c_root_path TYPE string VALUE `/sap/opu/odata4/sap/<SERVICE>/srvd_a2x/sap/<NAME>/0001/`.

 

POST Request

Da unsere POST Requests immer recht ähnlich aufgebaut sind, definieren wir eine Methode, die wir in den folgenden Verarbeitungen immer wieder verwenden werden und die uns eine flexible Schnittstelle zur Verfügung stellt. Die Definition der Typen sieht wie folgt aus:

TYPES:
  td_process TYPE char15,

  BEGIN OF ts_answer,
    code     TYPE i,
    reason   TYPE string,
    location TYPE string,
    content  TYPE string,
    action   TYPE string,
  END OF ts_answer,

  BEGIN OF ts_post_request,
    process  TYPE td_process,
    uri      TYPE string,
    payload  TYPE string,
    if_match TYPE string,
  END OF ts_post_request.


METHODS process_post
  IMPORTING is_post_request  TYPE ts_post_request
  RETURNING VALUE(rs_result) TYPE ts_answer
  RAISING   cx_t100_msg.

 

Für das Logging gibt es in "TS_POST_REQUEST" eine Prozess ID, um die Fehlermeldung besser zuordnen zu können. Die URI enthält den angefragten Endpunkt und in der Payload würden die Daten als JSON liegen. Das Feld IF_MATCH setzt später noch einen Header in der Anfrage. Die Implementierung der Methode sieht wie folgt aus:

METHOD process_post.
  DATA(ld_uri) = |{ c_root_path }{ is_post_request-uri }|.

  mo_http_client->request->set_method( if_http_request=>co_request_method_post ).
  mo_http_client->request->set_header_field( name = 'x-csrf-token' value = ms_auth-token ).
  mo_http_client->request->set_header_field( name = '~request_uri' value = ld_uri ).
  mo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/json' ).

  IF is_post_request-if_match IS NOT INITIAL.
    mo_http_client->request->set_header_field( name = 'If-Match' value = is_post_request-if_match ).
  ENDIF.

  IF is_post_request-payload IS NOT INITIAL.
    mo_http_client->request->set_cdata( is_post_request-payload ).
  ENDIF.

  process_send_and_receive( is_post_request-process ).

  mo_http_client->response->get_status( IMPORTING code   = rs_result-code
                                                  reason = rs_result-reason ).
  rs_result-content = mo_http_client->response->get_cdata( ).
ENDMETHOD.

 

Folgende Schritte werden in der Methode durchgeführt:

  • Erzeugung der Ziel URI 
  • Setzen der Header Informationen (Wichtig vor allem das Setzen des Tokens)
  • Übernahme der Payload
  • Senden und Empfangen der Anfrage
  • Auslesen des Status und des Contents

 

Token

Bevor wir nun unseren ersten POST Request gegen den Endpunkt absetzen können, benötigen wir einen gültigen X-CSRF-Token und eine gültige SAP Session auf dem ABAP Environment. Dazu setzen wir das entsprechende Header Feld auf "fetch". Die aufzurufende URI bauen wir entsprechend aus Root und Entitätsnamen zusammen und übergeben sie ebenfalls an den Header.

mo_http_client->request->set_header_field( name = 'x-csrf-token' value = 'fetch' ).
mo_http_client->request->set_header_field( name = '~request_uri' value = |{ c_root_path }Entity| ).

process_send_and_receive( ).

ms_auth-token = mo_http_client->response->get_header_field( 'x-csrf-token' ).

 

Zum Abschluss führen wir die Anfrage aus und holen uns aus dem Antwort Header den entsprechenden Token, den wir in einem Attribut in der Klasse speichern, da wir diesen noch für weitere Anfragen benötigen.

 

Anlegen

Als nächsten Schritt wollen wir nun einen neuen Eintrag in der Entität anlegen, dazu führen wir unseren ersten POST gegen die Schnittstelle aus. Zuerst müssen wir die Payload nach JSON konvertieren, dazu verwenden wir eine Struktur, die dem Zieltypen entspricht, aber Vorsicht, da hier nicht die CamelCase Notation verwendet wird, sondern alle Feldbezeichner klein bleiben. Im Anschluss starten wir die Anlage über die Methode PROCESS_POST für unsere Zielentität (siehe URI).

DATA(ld_payload) = NEW /ui2/cl_abap2json( )->struc2json( is_payload ).

DATA(ls_answer) = process_post( is_post_request = VALUE #( process = cs_process-create
                                                           uri     = `Entity`
                                                           payload = ld_payload ) ).

IF ls_answer-code = 201.
  ms_auth-location = mo_http_client->response->get_header_field( 'location' ).

ELSE.
  " Error Handling
ENDIF.

 

Der Server sollte uns ein HTTP Status "201 Created" melden, dann befindet sich ein neuer Eintrag in der Draft-Tabelle der Entität auf der BTP. In den Header Feldern erhalten wir auch im Feld "location" die nötige Informationen, um mit der neuen Entität zu arbeiten. Die Location übernehmen wir ebenfalls in unser Klassen Attribut, da wir es für die nächsten Anfragen benötigen.

 

Aktionen

Bevor wir nun die Aktionen ausführen können, benötigen wir erst einmal die entsprechende Information aus der Metadata des OData Services. Dazu den Endpunkt mit dem Zusatz $metadata aufrufen und in der XML Datei nach Activate suchen, entsprechend erhalten wir unsere definierten Actions.

 

Für die weitere Verarbeitung benötigen wir Prepare, Activate und Discard. Ebenso wichtig ist der Type, ansonsten wird die Aktion beim Ausführen nicht gefunden.

 

Prepare

Als nächster Schritt steht nun die Prepare Phase an, dazu bauen wir die URI mit Hilfe der gespeicherten Location auf, gefolgt von der Action mit dem Typ. Den Platzhalter und gegebenenfalls die Version musst du durch deine Daten austauschen. Die Anfrage geschieht wieder über einen POST Request an den Endpunkt. Wichtig bei diesem Schritt ist auch die Mitgabe des "IF-MATCH" Headers, hier hast du die Möglichkeit das ETag mitzugeben, in diesem Fall haben wir nur eine Instanz und geben einen Stern mit.

DATA(ld_uri) = |{ ms_auth-location }/com.sap.gateway.srvd_a2x.<NAME>.v0001.Prepare|.

DATA(ls_answer) = process_post( is_post_request = VALUE #( process  = cs_process-prepare
                                                           uri      = ld_uri
                                                           if_match = '*' ) ).

CASE ls_answer-code.
  WHEN 200 OR 204.
    " Success message

  WHEN OTHERS.
    add_error_to_log( ls_answer ).
    discard_draft( ).

    " Error Handling

ENDCASE.

 

Die Behandlung des Fehlers findest du im Abschnitt "Discard", dort gehen wir noch einmal auf das Mapping ein.

 

Activate

Wurde die Prepare Phase so weit ohne Fehler durchlaufen, kann der Activate durchgeführt werden. In dieser Phase werden die Validations im RAP auf der BTP durchlaufen und es können Fehlermeldungen zurückkommen, die eine Aktivierung des Datensatzes verhindern. Bei diesem Schritt ist ebenfalls der "IF-MATCH" Header wichtig.

DATA(ld_uri) = |{ ms_auth-location }/com.sap.gateway.srvd_a2x.<NAME>.v0001.Activate|.

DATA(ls_answer) = process_post( is_post_request = VALUE #( process  = cs_process-activate
                                                           uri      = ld_uri
                                                           if_match = '*' ) ).

CASE ls_answer-code.
  WHEN 200 OR 204.
    rs_result = ls_answer.

    " Success message

  WHEN OTHERS.
    add_error_to_log( ls_answer ).
    discard_draft( ).

    " Error Handling

ENDCASE.

 

Vom Quellcode her ähnlich zum Prepare, es erfolgt die gleiche Fehlerbehandlung am Ende der Verarbeitung. Wenn wir einen HTTP Status "200 OK" erhalten, befindest sich auch im Body der Antwort die entsprechenden Daten zur Entität. Aus diesen können wir nun auch den neuen Schlüssel ableiten. Dazu ein Stück Quellcode, um den JSON-String in eine interne Struktur zu konvertieren.

DATA ls_entity TYPE ts_entity.

/ui2/cl_json=>deserialize( EXPORTING json = is_answer-content
                           CHANGING  data = ls_entity ).

rd_result = ls_entity-key.

 

Discard

Löschen

Sollte es bei den Schritten Prepare oder Activate zu Fehlern kommen, dann wollen wir die "halbe" Instanz nicht stehen lassen, sondern diese wieder aus der Draft Tabelle entfernen. Dazu können wir nicht mit einem DELETE arbeiten, sondern müssen die Aktion "Discard" für den Datensatz auslösen.

DATA(ld_uri) = |{ ms_auth-location }/com.sap.gateway.srvd_a2x.<NAME>.v0001.Discard|.

DATA(ls_answer) = process_post( is_post_request = VALUE #( process = cs_process-discard
                                                           uri     = ld_uri ) ).

CASE ls_answer-code.
  WHEN 200 OR 204.
    " Success message

  WHEN OTHERS.
    " Error Handling

ENDCASE.

 

Zum Abschluss erhalten wir den HTTP Status "200 OK" und die Instanz wurde aus der Draft Tabelle entfernt.

 

Fehlerbehandlung

Im Falle eines Fehlers kann der Body auch geparst werden, um die Fehlermeldungen zu extrahieren. Schauen wir uns im ersten Schritt einmal eine komplexe Meldung an.

 

Die Message im oberen Bereich ist die Hauptmeldung für den Fehler, im Detailbereich werden die weiteren Meldungen aufgelistet, die während der Validierung erzeugt wurden. Entsprechend legen wird für das Parsen der Meldung einen Typen an.

TYPES:
  BEGIN OF ts_detail,
    code    TYPE string,
    message TYPE string,
  END OF ts_detail,
  tt_detail TYPE STANDARD TABLE OF ts_detail WITH EMPTY KEY,

  BEGIN OF ts_error,
    code    TYPE string,
    message TYPE string,
    details TYPE tt_detail,
  END OF ts_error,

  BEGIN OF ts_message,
    error TYPE ts_error,
  END OF ts_message.

 

Im letzten Schritt parsen wir das JSON in eine interne Struktur und können dann die Meldungen in unser Logobjekt übernehmen oder auf eine andere Weise ausgeben. Die TODOs sind im Quellcode markiert und müssen entsprechend implementiert werden.

DATA ls_message TYPE ts_message.

/ui2/cl_json=>deserialize( EXPORTING json = is_answer-content
                           CHANGING  data = ls_message ).

" TODO: Log ls_message-error-message

LOOP AT ls_message-error-details INTO DATA(ls_detail).
  " TODO: Log ls_detail-message
ENDLOOP.

 

Komplettes Beispiel

Wie immer hier noch einmal das komplette Beispiel dieses Artikels. Das Beispiel ist dieses Mal sehr lang und wird nicht ohne Anpassungen funktionieren. Erst einmal benötigst du eine Verbindung Richtung Cloud und dann einen entsprechenden Endpunkt als OData v4.

CLASS zcl_24bs_create_review DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

  PRIVATE SECTION.
    TYPES:
      td_process TYPE char15,

      BEGIN OF ts_answer,
        code     TYPE i,
        reason   TYPE string,
        location TYPE string,
        content  TYPE string,
        action   TYPE string,
      END OF ts_answer,

      BEGIN OF ts_auth,
        token    TYPE string,
        location TYPE string,
      END OF ts_auth,

      BEGIN OF ts_post_request,
        process  TYPE td_process,
        uri      TYPE string,
        payload  TYPE string,
        if_match TYPE string,
      END OF ts_post_request,

      BEGIN OF ts_payload,
        field1 TYPE string,
        field2 TYPE string,
        field3 TYPE string,
      END OF ts_payload,

      BEGIN OF ts_detail,
        code    TYPE string,
        message TYPE string,
      END OF ts_detail,
      tt_detail TYPE STANDARD TABLE OF ts_detail WITH EMPTY KEY,

      BEGIN OF ts_error,
        code    TYPE string,
        message TYPE string,
        details TYPE tt_detail,
      END OF ts_error,

      BEGIN OF ts_message,
        error TYPE ts_error,
      END OF ts_message,

      BEGIN OF ts_entity,
        key            TYPE char32,
        status         TYPE char2,
        isactiveentity TYPE abap_bool,
      END OF ts_entity.

    CONSTANTS c_root_path   TYPE string VALUE `/sap/opu/odata4/sap/<SERVICE>/srvd_a2x/sap/<NAME>/0001/`. " TODO
    CONSTANTS c_destination TYPE string VALUE 'TEST_xxx'.                                                " TODO

    CONSTANTS:
      BEGIN OF cs_process,
        token    TYPE td_process VALUE 'TOKEN',
        create   TYPE td_process VALUE 'CREATE_ENTITY',
        prepare  TYPE td_process VALUE 'PREPARE',
        activate TYPE td_process VALUE 'ACTIVATE',
        discard  TYPE td_process VALUE 'DISCARD',
      END OF cs_process.

    DATA mo_http_client TYPE REF TO if_http_client.
    DATA ms_auth        TYPE ts_auth.

    METHODS create_token_and_cookie
      RAISING cx_t100_msg.

    METHODS create_entity
      IMPORTING is_payload TYPE ts_payload
      RAISING   cx_t100_msg.

    METHODS process_send_and_receive
      IMPORTING id_process TYPE td_process
      RAISING   cx_t100_msg.

    METHODS process_post
      IMPORTING is_post_request  TYPE ts_post_request
      RETURNING VALUE(rs_result) TYPE ts_answer
      RAISING   cx_t100_msg.

    METHODS prepare
      RAISING cx_t100_msg.

    METHODS activate
      RETURNING VALUE(rs_result) TYPE ts_answer
      RAISING   cx_t100_msg.

    METHODS discard_draft
      RAISING cx_t100_msg.

    METHODS extract_key_from_content
      IMPORTING is_answer        TYPE ts_answer
      RETURNING VALUE(rd_result) TYPE char32.

    METHODS add_error_to_log
      IMPORTING is_answer TYPE ts_answer.
ENDCLASS.


CLASS zcl_24bs_create_review IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    CLEAR ms_auth.
    cl_http_client=>create_by_destination( EXPORTING destination = CONV char20( c_destination )
                                           IMPORTING client      = mo_http_client ).

    mo_http_client->propertytype_accept_cookie = if_http_client=>co_enabled.

    TRY.
        create_token_and_cookie( ).
        create_entity( VALUE #( ) ).
        prepare( ).
        DATA(ls_activated_entity) = activate( ).

        DATA(ld_new_key) = extract_key_from_content( ls_activated_entity ).

      CATCH cx_t100_msg.
        " TODO: Error Handling
    ENDTRY.

    mo_http_client->close( ).

    " TODO: Set returning values
  ENDMETHOD.


  METHOD create_token_and_cookie.
    mo_http_client->request->set_header_field( name = 'x-csrf-token' value = 'fetch' ).
    mo_http_client->request->set_header_field( name = '~request_uri' value = |{ c_root_path }Review| ).

    process_send_and_receive( cs_process-token ).

    ms_auth-token = mo_http_client->response->get_header_field( 'x-csrf-token' ).
  ENDMETHOD.


  METHOD create_entity.
    DATA(ld_payload) = NEW /ui2/cl_abap2json( )->struc2json( is_payload ).

    DATA(ls_answer) = process_post( is_post_request = VALUE #( process = cs_process-create
                                                               uri     = `Entity`
                                                               payload = ld_payload ) ).

    IF ls_answer-code = 201.
      ms_auth-location = mo_http_client->response->get_header_field( 'location' ).
    ELSE.
      " TODO: Error Handling
    ENDIF.
  ENDMETHOD.


  METHOD process_post.
    DATA(ld_uri) = |{ c_root_path }{ is_post_request-uri }|.

    mo_http_client->request->set_method( if_http_request=>co_request_method_post ).
    mo_http_client->request->set_header_field( name = 'x-csrf-token' value = ms_auth-token ).
    mo_http_client->request->set_header_field( name = '~request_uri' value = ld_uri ).
    mo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/json' ).

    IF is_post_request-if_match IS NOT INITIAL.
      mo_http_client->request->set_header_field( name = 'If-Match' value = is_post_request-if_match ).
    ENDIF.

    IF is_post_request-payload IS NOT INITIAL.
      mo_http_client->request->set_cdata( is_post_request-payload ).
    ENDIF.

    process_send_and_receive( is_post_request-process ).

    mo_http_client->response->get_status( IMPORTING code   = rs_result-code
                                                    reason = rs_result-reason ).
    rs_result-content = mo_http_client->response->get_cdata( ).
  ENDMETHOD.


  METHOD prepare.
    DATA(ld_uri) = |{ ms_auth-location }/com.sap.gateway.srvd_a2x.<NAME>.v0001.Prepare|.

    DATA(ls_answer) = process_post( is_post_request = VALUE #( process  = cs_process-prepare
                                                               uri      = ld_uri
                                                               if_match = '*' ) ).

    CASE ls_answer-code.
      WHEN 200 OR 204.
        " TODO: Success message

      WHEN OTHERS.
        add_error_to_log( ls_answer ).
        discard_draft( ).

        " TODO: Error Handling

    ENDCASE.
  ENDMETHOD.


  METHOD activate.
    DATA(ld_uri) = |{ ms_auth-location }/com.sap.gateway.srvd_a2x.<NAME>.v0001.Activate|.

    DATA(ls_answer) = process_post( is_post_request = VALUE #( process  = cs_process-activate
                                                               uri      = ld_uri
                                                               if_match = '*' ) ).

    CASE ls_answer-code.
      WHEN 200 OR 204.
        rs_result = ls_answer.

        " TODO: Success message

      WHEN OTHERS.
        add_error_to_log( ls_answer ).
        discard_draft( ).

        " TODO: Error Handling

    ENDCASE.
  ENDMETHOD.


  METHOD discard_draft.
    DATA(ld_uri) = |{ ms_auth-location }/com.sap.gateway.srvd_a2x.<NAME>.v0001.Discard|.

    DATA(ls_answer) = process_post( is_post_request = VALUE #( process = cs_process-discard
                                                               uri     = ld_uri ) ).

    CASE ls_answer-code.
      WHEN 200 OR 204.
        " TODO: Success message

      WHEN OTHERS.
        " TODO: Error Handling

    ENDCASE.
  ENDMETHOD.


  METHOD process_send_and_receive.
    mo_http_client->send( EXCEPTIONS http_communication_failure = 1
                                     http_invalid_state         = 2
                                     http_processing_failed     = 3
                                     http_invalid_timeout       = 4
                                     OTHERS                     = 5 ).
    IF sy-subrc <> 0.
      " TODO: Error Handling
    ENDIF.

    mo_http_client->receive( EXCEPTIONS http_communication_failure = 1
                                        http_invalid_state         = 2
                                        http_processing_failed     = 3
                                        OTHERS                     = 4 ).
    IF sy-subrc <> 0.
      " TODO: Error Handling
    ENDIF.
  ENDMETHOD.


  METHOD extract_key_from_content.
    DATA ls_entity TYPE ts_entity.

    /ui2/cl_json=>deserialize( EXPORTING json = is_answer-content
                               CHANGING  data = ls_entity ).

    rd_result = ls_entity-key.
  ENDMETHOD.


  METHOD add_error_to_log.
    DATA ls_message TYPE ts_message.

    /ui2/cl_json=>deserialize( EXPORTING json = is_answer-content
                               CHANGING  data = ls_message ).

    " TODO: Log ls_message-error-message

    LOOP AT ls_message-error-details INTO DATA(ls_detail).
      " TODO: Log ls_detail-message
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

 

Learnings

Zum Zeitpunkt der Implementierung gab es leider keine Quelle bei SAP, die beschrieb wie man so etwas genau durchführt und auch nicht die ganzen Besonderheiten, die es zu beachten gibt. Hier noch einmal kurz die Zusammenfassung und die Lernings der Anbindung:

  • Aktivierung der Cookies im HTTP Client (ACCEPT_COOKIE)
  • Beachtung des RAP Flows (Prepare -> Activate)
  • Ermittlung der korrekten Namen der Aktionen
  • Löschen der Instanz bei Fehler (Discard)
  • Verwendung des IF-MATCH Header für die Draft Instanz

 

Fazit

Die Implementierung solch einer Funktion ist nicht so schwer, wenn man alle Probleme gelöst hat. Doch da solche konkreten Beispiele aktuell fehlen, kann die Recherche aufwändig sein. Wenn du die Funktionsweise erst einmal verstand hast, dann sollten die weiteren Implementierungen kein Problem mehr sein und du für die nächsten Anfragen gewappnet sein.


Enthaltene Themen:
BTPODatav4POSTDraftCreate Entity
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Freitag neuen Content im Bereich ABAP und unregelmäßig in allen anderen Bereichen. Schaue bei unseren Tools und Apps vorbei, diese stellen wir kostenlos zur Verfügung.


RAP - Events

Kategorie - ABAP

Wie kannst du eigentlich Events in RAP erzeugen und mit ABAP verarbeiten? Hier erfährst du mehr zur eventgetriebenen Verarbeitung.

23.12.2024

RAP - Excel Datei laden

Kategorie - ABAP

In diesem praktischen Beispiel schauen wir uns die Verarbeitung von Excel in ABAP mit den neuen XCO Klassen an und wie wir die Datei in unser RAP Objekt bekommen.

20.12.2024

RAP - Semantischer Schlüssel

Kategorie - ABAP

Wofür benötigst du den semantischen Schlüssel und wie wird er im ABAP RESTful Programming Model dargestellt? Hier gibt es mehr dazu.

13.12.2024

RAP - Upload von Dateien (Stream)

Kategorie - ABAP

Wie kannst du einfach Dateien in deine RAP Entität laden und diese in ABAP zur Verfügung stellen? Hier schauen wir uns einmal die Details an.

10.12.2024

RAP - Report Pattern

Kategorie - ABAP

Wie ist das Report Pattern in RAP aufgebaut und was kannst du damit machen? Mehr dazu in diesem ABAP Artikel.

06.12.2024