Skip to Content
Technical Articles
Author's profile photo Sreekanth Pavoor

Consume OData Deep Structure In ABAP

Recently I have come across a requirement to consume OData service from a different system in our system using ABAP programing. There are some blog post already about how to do this, my blog post is an extension to this.

Business Scenario

Wanted to extract some data from a different system. The source system is having an OData service for exposing the master data. OData output is a deep structured data (Header & Item data together using $expand), converting this data in to an ABAP internal table was little tricky. Would like to share the solution which I implemented.

Code for getting the OData service output and converting the data in to ABAP format.

class Z_CL_ODATA_UTILITY definition
  public
  final
  create public .

public section.
  class-methods GET_RESULT_FROM_ODATA_SRV_DEEP
    importing
      !IV_URI type STRING
      !IV_DESTINATION type C
    exporting
      !E_DATA type DATA
      !ET_MESSAGE type BAL_T_MSG .
ENDCLASS.


CLASS Z_CL_ODATA_UTILITY IMPLEMENTATION.

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method Z_CL_ODATA_UTILITY=>GET_RESULT_FROM_ODATA_SRV_DEEP
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_URI                         TYPE        STRING
* | [--->] IV_DESTINATION                 TYPE        C
* | [<---] E_DATA                         TYPE        DATA
* | [<---] ET_MESSAGE                     TYPE        BAL_T_MSG
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD get_result_from_odata_srv_deep.
    DATA lv_uri TYPE string.

*-->Create HTTP client object using destination
    TRY.
        CALL METHOD cl_http_client=>create_by_destination
          EXPORTING
            destination              = iv_destination
          IMPORTING
            client                   = DATA(lo_http_client)
          EXCEPTIONS
            argument_not_found       = 1
            destination_not_found    = 2
            destination_no_authority = 3
            plugin_not_active        = 4
            internal_error           = 5
            OTHERS                   = 6.
        IF sy-subrc = 0.
          IF lo_http_client IS BOUND.
            lv_uri = iv_uri.
*-->Always get the output in JSON format. No JSON format if the count is requested
            IF iv_uri NS '/$count' AND iv_uri NS '&$format=json'.
              lv_uri = iv_uri && |&$format=json|.
            ENDIF.
*-->Set URI to be executed in the request object
            CALL METHOD cl_http_utility=>set_request_uri
              EXPORTING
                request = lo_http_client->request
                uri     = lv_uri. 
*-->Set request method as GET
            lo_http_client->request->set_method( if_http_request=>co_request_method_get ).
*-->Send the request
            CALL METHOD lo_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.
*-->Recive the response
              CALL METHOD lo_http_client->receive
                EXCEPTIONS
                  http_communication_failure = 1
                  http_invalid_state         = 2
                  http_processing_failed     = 3
                  OTHERS                     = 4.
              IF sy-subrc = 0.
*-->Extract data in the form of JSON from the response
                DATA(lv_json_response) = lo_http_client->response->get_cdata( ).
*-->Convert the JSON data in to ABAP format
                IF iv_uri CS '/$count'.
                  TRY.
                      e_data = lv_json_response.
                    CATCH cx_root.
                  ENDTRY.
                ELSE.
                  /ui2/cl_json=>deserialize(
                    EXPORTING
                      json             = lv_json_response
                    CHANGING
                      data             = e_data  ).
                ENDIF.
              ENDIF.
            ENDIF.
          ENDIF.
        ENDIF.
      CATCH cx_root INTO DATA(lo_exception).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

 

It is important to follow the output structure type (ls_data in below example) definition same as OData structure.

*-->Define the structure for receiving the result
  types:
    BEGIN OF ty_marm,
            results TYPE z_t_marm,
          END OF ty_marm.
  types:
    BEGIN OF ty_marc,
            results TYPE z_t_marc,
          END OF ty_marc.
  types:
    BEGIN OF ty_materials,
            matnr             TYPE  matnr,
            ersda             TYPE  ersda,
            pstat             TYPE  pstat_d,
            mtart             TYPE  mtart,
            navtomarm TYPE ty_marm,
            navtomarc TYPE ty_marc,
          END OF ty_materials .
  types:
    tt_materials TYPE STANDARD TABLE OF ty_materials WITH DEFAULT KEY .
  types:
    BEGIN OF ty_d,
            __count TYPE int4, "Optinal. Needed only if we are getting the inlinecount
            results TYPE tt_materials,
          END OF ty_d .
  types:
    BEGIN OF ty_data,
            d TYPE ty_d,
          END OF ty_data .
  DATA: ls_data  TYPE ty_data.

  z_cl_odata_utility=>get_result_from_odata_srv_deep(
        EXPORTING
          iv_uri         = |MY_SERVICE_SRV/UnpackSet?$filter=(Ersda ge datetime'{ lv_from_ts }' or | &&
                           |Ersda le datetime'{ lv_to_ts }') and Mtart eq 'HALB' | &&
                           |&$expand=navtomarm,navtomarc&$inlinecount=allpages|
          iv_destination = 'MYDES099_HTTP'
        IMPORTING
          e_data        = ls_data
          et_message    = et_message     " Application Log: Table with Messages
      ).

Conclusion

Now you know,
How to consume OData services in ABAP program.
How to receive deep structured data from an OData service and convert it into ABAP data format.
How to consume OData service from a different system.

Questions & Other solutions are welcome! 🙂

Assigned Tags

      2 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Andre Fischer
      Andre Fischer

      What was the release you have been working on?

      Author's profile photo Sreekanth Pavoor
      Sreekanth Pavoor
      Blog Post Author

      NW 7.50.

      Is there any alternative or better solution in any releases? Thanks!