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)

267

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 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.


BTP - External Entities

Kategorie - ABAP

Was machen eigentlich External Entities in ABAP und wie kannst du damit einfach per SDA Daten aus einer On-Prem Datenbank lesen? Mehr Details in diesem Artikel.

20.05.2025

RAP - Mehrere Filter und Einstellungen

Kategorie - ABAP

Wie sieht es eigentlich aus, wenn wir in RAP mehrere Filter und Felder als Standard setzen wollen und dazu noch eine standardmäßige Sortierung benötigen?

16.05.2025

RAP - Länge von Meldungen

Kategorie - ABAP

Deine Meldung wird bei der Ausgabe mit RAP abgeschnitten? Lass uns das Problem und eine Lösung anschauen.

13.05.2025

RAP - Suchhilfe und Schlüssel optimieren

Kategorie - ABAP

In diesem Artikel optimieren wir unsere Suchhilfen im Custom Pattern, verwenden das Additional Binding und machen unsere RAP Anwendung fit für den Endanwender.

06.05.2025

RAP - Festwert-Filter

Kategorie - ABAP

Wie verwendest du Festwerte aus einer Domäne für einen Filter und passt diesen nach deinen Bedüfnissen in RAP an? Mehr dazu hier.

02.05.2025