This is a test message to test the length of the message box.
Login
|
BTP On-Premise (OData)
Erstellt von Software-Heroes

BTP - Zugriffsmethoden On-Premise (OData)

420

In diesem Artikel schauen wir uns die anderen Zugriffmethoden auf einen OData Service über die Proxy Klassen an.

Werbung


Im letzten Artikel haben wir uns angeschaut, wie wir einen OData Service im ABAP Environment zur Verfügung stellen und zum ersten Mal auch aufrufen. Neben dem Holen von Daten gibt es aber auch andere Szenarien, mit der API im Backend zu arbeiten, diese wollen wir uns in diesem Artikel näher anschauen.

 

Einleitung

Wie bereits im letzten Artikel angesprochen, müssen wir vor dem Zugriff eine Proxy Klasse erzeugen, über die wir unser Proxy Objekt erzeugen können, um auf das Backend zugreifen zu können. Wir verwenden in diesem Fall wieder eine Destination aus dem Destination Service und erzeugen das Objekt in einer eigenen Methode GET_PROXY. Diese Methode verwenden wir in allen folgenden Beispielen:

DATA(lo_destination) = cl_http_destination_provider=>create_by_cloud_destination(
  i_name       = c_destination
  i_authn_mode = if_a4c_cp_service=>service_specific
).

DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).

ro_result = cl_web_odata_client_factory=>create_v2_remote_proxy(
  EXPORTING
    iv_service_definition_name = 'ZBS_DEMO_RAP_ONPREM_ODATA'
    io_http_client             = lo_client
    iv_relative_service_root   = '/sap/opu/odata/sap/ZBS_API_COMPANY_NAMES_O2' ).

 

READ mit Filter

Beim letzten Zugriff hatten wir alle Daten der Schnittstelle gelesen, in diesem Beispiel wollen wir einmal einen Filter auf ein Feld anwenden, um nur eine Teilmenge der Daten zu lesen. Im ersten Schritt erstellen wir eine Range mit den entsprechenden Filtern und erzeugen dann ein Objekt zum Lesen. Im Anschluss erzeugen wir eine Filter-Factory und bauen einen Filter für den Zugriff auf.

DATA:
  lt_r_branch TYPE RANGE OF zbs_rap_companynames-Branch,
  lt_found    TYPE STANDARD TABLE OF zbs_rap_companynames.

lt_r_branch = VALUE #( sign = 'I' option = 'EQ'
  ( low = 'Software' )
  ( low = 'Food' )
).

DATA(lo_request) = get_proxy( )->create_resource_for_entity_set( c_entity )->create_request_for_read( ).

" Create filter object 
DATA(lo_filter_factory) = lo_request->create_filter_factory( ).
DATA(lo_filter)  = lo_filter_factory->create_by_range( iv_property_path = 'BRANCH' it_range = lt_r_branch ).
lo_request->set_filter( lo_filter ).

DATA(lo_response) = lo_request->execute( ).
lo_response->get_business_data( IMPORTING et_business_data = lt_found ).

 

Es werden nun aus dem Backend die gefundenen Einträge in LT_FOUND zurückgegeben, diese entsprechen unserem angewandten Filter:

 

CREATE

Im zweiten Beispiel wollen wir einen neuen Datensatz On-Premise erzeugen. Dazu definieren wir uns eine Struktur mit den neuen Werten, der Schlüssel der Entität muss aber mindestens gefüllt sein. Dann erzeugen wir uns  ein Objekt für die Anlage und übergeben die Daten. Am Ende führen wir die Anfrage per Execute aus.

DATA:
  ls_created TYPE zbs_rap_companynames.

DATA(ls_new_company) = VALUE zbs_rap_companynames(
  CompanyName = 'Gazprom'
  Branch = 'Gas'
).

DATA(lo_request) = get_proxy( )->create_resource_for_entity_set( c_entity )->create_request_for_create( ).
lo_request->set_business_data( ls_new_company ).

DATA(lo_response) = lo_request->execute( ).
lo_response->get_business_data( IMPORTING es_business_data = ls_created ).

 

Wenn wir uns die Tabelle im Data-Preview anschauen, wurde der neue Datensatz angelegt. Mit einer weiteren Leseabfrage, könnten wir dann die Daten ermitteln:

 

UPDATE

Den zuvor angelegten Datensatz wollen wir in diesem Schritt nun aktualisieren und eine Beschreibung mitgeben. Dazu definieren wir uns zwei Strukturen, eine für den Schlüssel und eine mit den Daten. Bevor wir das Update-Objekt erzeugen können, müssen wir über den Schlüssel navigieren. Beim Update setzen wir die HTTP Methode auf PUT. Zum Abschluss übergeben wir wieder die neuen Daten und führen die Anfrage aus.

DATA:
  ls_updated TYPE zbs_rap_companynames.

DATA(ls_key) = VALUE zbs_rap_companynames( companyname = 'Gazprom' ).

DATA(ls_update_company) = VALUE zbs_rap_companynames(
  companyname         = 'Gazprom'
  branch              = 'Gas'
  companydescription  = `PJSC Gazprom is a Russian majority state-owned multinational energy corporation headquartered in the Lakhta Center in Saint Petersburg.`
).

DATA(lo_request) = get_proxy( )->create_resource_for_entity_set( c_entity
  )->navigate_with_key( ls_key
  )->create_request_for_update( /iwbep/if_cp_request_update=>gcs_update_semantic-put
).
lo_request->set_business_data( ls_update_company ).

DATA(lo_response) = lo_request->execute( ).
lo_response->get_business_data( IMPORTING es_business_data = ls_updated ).

 

In diesem Fall sind nun die Daten über den Data-Preview vollständig und wir sehen die befüllte Beschreibung im Backend System:

 

DELETE

Zum Abschluss wollen wir den Datensatz wieder aus dem System entfernen. In diesem Fall benötigen wir nur die Schlüssel-Struktur, navigieren über diese und erzeugen uns ein Objekt zum Löschen. Am Ende reicht das Ausführen der Abfrage und der Datensatz wird gelöscht.

DATA(ls_key) = VALUE zbs_rap_companynames( companyname = 'Gazprom' ).

DATA(lo_request) = get_proxy( )->create_resource_for_entity_set( c_entity
  )->navigate_with_key( ls_key
  )->create_request_for_delete(
).

lo_request->execute( ).

io_out->write( `Company deleted` ).

 

Vollständiges Beispiel

Hier noch einmal die vollständige Beispielklasse mit der Ausführung. Damit diese läuft, muss noch eine existierende Destination eingefügt werden und die API im Zielsystem laufen:

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

  PROTECTED SECTION.
  PRIVATE SECTION.
    CONSTANTS:
      c_destination TYPE string VALUE `<destination-service-id>`,
      c_entity      TYPE /iwbep/if_cp_runtime_types=>ty_entity_set_name VALUE 'COMPANYNAMES'.

    METHODS:
      get_proxy
        RETURNING VALUE(ro_result) TYPE REF TO /iwbep/if_cp_client_proxy,

      read_data_with_filter
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out
        RAISING
          /iwbep/cx_gateway,
      create_new_company
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out
        RAISING
          /iwbep/cx_gateway,
      update_company_description
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out
        RAISING
          /iwbep/cx_gateway,
      delete_company
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out
        RAISING
          /iwbep/cx_gateway.
ENDCLASS.


CLASS zcl_bs_demo_odata_actions IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    TRY.
        read_data_with_filter( out ).
        create_new_company( out ).
        update_company_description( out ).
        delete_company( out ).

      CATCH cx_root INTO DATA(lo_error).
        out->write( lo_error->get_text( ) ).
    ENDTRY.
  ENDMETHOD.


  METHOD get_proxy.
    TRY.
        DATA(lo_destination) = cl_http_destination_provider=>create_by_cloud_destination(
          i_name       = c_destination
          i_authn_mode = if_a4c_cp_service=>service_specific
        ).

        DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).

        ro_result = cl_web_odata_client_factory=>create_v2_remote_proxy(
          EXPORTING
            iv_service_definition_name = 'ZBS_DEMO_RAP_ONPREM_ODATA'
            io_http_client             = lo_client
            iv_relative_service_root   = '/sap/opu/odata/sap/ZBS_API_COMPANY_NAMES_O2' ).

      CATCH cx_root.
    ENDTRY.
  ENDMETHOD.


  METHOD read_data_with_filter.
    DATA:
      lt_r_branch TYPE RANGE OF zbs_rap_companynames-Branch,
      lt_found    TYPE STANDARD TABLE OF zbs_rap_companynames.

    lt_r_branch = VALUE #( sign = 'I' option = 'EQ'
      ( low = 'Software' )
      ( low = 'Food' )
    ).

    DATA(lo_request) = get_proxy( )->create_resource_for_entity_set( c_entity )->create_request_for_read( ).

    DATA(lo_filter_factory) = lo_request->create_filter_factory( ).
    DATA(lo_filter)  = lo_filter_factory->create_by_range( iv_property_path = 'BRANCH' it_range = lt_r_branch ).
    lo_request->set_filter( lo_filter ).

    DATA(lo_response) = lo_request->execute( ).
    lo_response->get_business_data( IMPORTING et_business_data = lt_found ).

    io_out->write( `Read with filter active:` ).
    io_out->write( lt_found ).
  ENDMETHOD.


  METHOD create_new_company.
    DATA:
      ls_created TYPE zbs_rap_companynames.

    DATA(ls_new_company) = VALUE zbs_rap_companynames(
      CompanyName = 'Gazprom'
      Branch = 'Gas'
    ).

    DATA(lo_request) = get_proxy( )->create_resource_for_entity_set( c_entity )->create_request_for_create( ).
    lo_request->set_business_data( ls_new_company ).

    DATA(lo_response) = lo_request->execute( ).
    lo_response->get_business_data( IMPORTING es_business_data = ls_created ).

    io_out->write( `Created new company:` ).
    io_out->write( ls_created ).
  ENDMETHOD.


  METHOD update_company_description.
    DATA:
      ls_updated TYPE zbs_rap_companynames.

    DATA(ls_key) = VALUE zbs_rap_companynames( companyname = 'Gazprom' ).

    DATA(ls_update_company) = VALUE zbs_rap_companynames(
      companyname         = 'Gazprom'
      branch              = 'Gas'
      companydescription  = `PJSC Gazprom is a Russian majority state-owned multinational energy corporation headquartered in the Lakhta Center in Saint Petersburg.`
    ).

    DATA(lo_request) = get_proxy( )->create_resource_for_entity_set( c_entity
      )->navigate_with_key( ls_key
      )->create_request_for_update( /iwbep/if_cp_request_update=>gcs_update_semantic-put
    ).
    lo_request->set_business_data( ls_update_company ).

    DATA(lo_response) = lo_request->execute( ).
    lo_response->get_business_data( IMPORTING es_business_data = ls_updated ).

    io_out->write( `Updated company:` ).
    io_out->write( ls_updated ).
  ENDMETHOD.


  METHOD delete_company.
    DATA(ls_key) = VALUE zbs_rap_companynames( companyname = 'Gazprom' ).

    DATA(lo_request) = get_proxy( )->create_resource_for_entity_set( c_entity
      )->navigate_with_key( ls_key
      )->create_request_for_delete(
    ).

    lo_request->execute( ).

    io_out->write( `Company deleted:` ).
  ENDMETHOD.
ENDCLASS.

 

Fazit

Die Arbeit mit den Daten im Backend ist relativ einfach und folgt immer dem gleichen Schema. Im angelegten Consumption Modell bekommst du immer einige rudimentäre Beispiele, wie du die Abfragen Richtung On-Premise durchführen kannst oder du nutzt einfach unseren Artikel dafür.


Enthaltene Themen:
BTPRAPABAP EnvironmentOn-PremiseOData
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Dienstag und 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 - Mixed Content

Kategorie - ABAP

Wie bekommen wir eigentlich unterschiedlichen Content in die gleiche Spalte im List Report? Schauen wir uns dazu einmal ein praktisches Beispiel für unsere Sales App an.

10.02.2026

RAP - Augmentation

Kategorie - ABAP

In diesem Artikel stellen wir unser Datenmodell der RAP Anwendung um und ändern die Form wie wir mit den Texten umgehen. Dabei verwenden wir Augmentation, um unser Datenmodell trotzdem vollständig zu halten.

03.02.2026

RAP - Virtuelle Felder sortieren

Kategorie - ABAP

Haben wir virtuelle Felder in einer Entität im ABAP RESTful Application Programming Model implementiert, wie können wir dann eigentlich eine Sortierung verwenden? Schauen wir uns einmal den Prozess dazu an.

23.01.2026

RAP - Multi-Input Field

Kategorie - ABAP

Eine ganze Entität in einem Feld darstellen? Mit dem Multi-Input Field möglich. Heute schauen wir uns den Punkt in ABAP für die RAP Entwicklung an und schauen uns die Szenarien an.

20.01.2026

RAP - Generierung mit Template

Kategorie - ABAP

Die Generatoren in RAP sind mächtig, wenn es um die schnelle Bereitstellung von RAP Objekten geht. Über Templates kannst du die Entitäten noch einmal schneller anlegen, wenn du eine Schulung machst.

13.01.2026