Skip to Content

Overview

  • In this blog, we try to consume a REST-Services in an OData-Service.
  • Here we use GET operation of OData-Service
  • and while consuming the REST-Service, we use HTTP-Method as POST to send request message and in acknowledgement REST-Service provides response which will be mapped to OData-Service’s structure.
  • This blogs is a business case example of parent blog:

Business Scenario:

  • In a fiori-app, where data need to be accessed from a non-sap system.
  • This non-sap system has a REST-Service technique for data exchange to out-side world.
  • So, in fiori-App, we need an oData-Service which can consume/talk to non-sap’s REST-Service for data Exchange.
  • Note: Here we can consume REST-Services directly in fiori-App, but we recommend to access this via oData-Service, due to following reasons:
    • The Cross-domain issue in JavaScript codes while accessing REST-Services when we deploy fiori-App in Fiori-Server.

REST Service Details:

  • This REST-Service of non-sap system is a medium for data exchange between SAP-FioriApp and non-sap system
  • REST (REpresenational State Transfer) is an architectural style that uses simple and lightweight mechanism for inter-machine communication.
  • In this blog’s example, this REST-Service has following components for data-exchange:
    1. EndPoint-URL:
      • This consists of http(s), host, port and RestProjectPath of Non-SAP system
      • For Example:
        • http://<ServiceIP>:<Port>/<REST_Service_Path>
    2. Access-credentials:
      • user-id and password which is required to access this REST service
    3.  Request-Message:
      • This is the input format which respective REST-Service understands, for which it runs its program logic and returns data accordingly.
      • Here, below is the JASON input format:
      • [  
           {  
              "taskId":286079
           },
           {  
              "taskId":287571
           }
        ]
    4. Response-Message:
      • This is the output message format which we receive from REST-Service in acknowledgement.
      • Here, output format is like:
      • {  
           "response":"Success",
           "responseData":{  
              "response":"Posted successfully"
           },
           "error":null,
           "errorList":[]
        }
  • REST Services are working with ‘Resources’ instead of ‘Operations’

Steps to create oData Service [with GET_ENTITYSET]:

  • To Consume above REST-Service, we implement oData-Service in following manner:
    • Creation of an EntitySet which will have two Property:
      • REQUEST
        • To send JSON-Input in given REST-Service format
      • RESPONSE
        • To receive JSON-output from REST-Service.
    • Re-Definition of method ‘GET_ENTITYSET‘ of respective Enity, where we write ABAP-Code to consume REST-Service.
  • Following detailed Steps can be followed for same:

[1] Create an EntityType and EntitySet 

  • To Create an OData-Serivice, go-to SAP-Firoi-Server t-code ‘SEGW’
  • Right click on Project’s folder ‘Entity Types’ to create an Entity
  • with Name ‘ConsumeREST’ with EntitySet name ‘ConsumeRESTSet’
  • Create two properties (REQUEST and RESPONSE) and make REQUEST as key.
  • Save and ‘Generate Runtime object’ by clicking circle icon (red/white)  with project selection.
  • Thus meta-structure for EntitySet gets created.

 

[2] Redefine method ‘ConsumeRESTSet_GET_ENTITYSET

  • Next we need to re-define method ‘GET_ENTITYSET‘ where abap-code will be written to consume REST service. This method will have following functionalities:
    • Get input from property ‘REQUEST’ of ODataService’s EntitySet ‘ConsumeRESTSet’
    • Consume/trigger REST-Service with this input
    • In acknowledgement, REST-Service provide response, extract it and map it to oDataService’s EntitySet ‘ConsumeRESTSet’ in property ‘RESPONSE’
  • To re-define same, go to Odata-Service project’s folder ‘Runtiime Artifacts’ -> select ‘DPC_EXT’ class -> double click on it to go to abap runtime workbench
  • Below is ‘_DPC_EXT’ class, where we re-define ‘GET_ENTITYSET
  • Go to folder ‘_DPC_EXT’ -> folder ‘Methods’ -> folder ‘Inherited Methods’
  • select method ‘ConsumeRESTSet_GET_ENTITYSET‘ -> right click -> select ‘Redefine’
  • Once method redefined, it get listed inside folder ‘Methods/Redefinitions’
  • and we write abap-code iside this method to do following tasks:
    • To read input from property ‘REQUEST’ of ODataService’s EntitySet ‘ConsumeRESTSet’
    • Call REST-Service by sending input and using its endpoint url
    • In acknowledgement, REST-Service provide response,
    • extract it and map it to oDataService’s EntitySet ‘ConsumeRESTSet’ in property ‘RESPONSE’
  • Please note:
    • We can not do it in redefinition of GET_ENTITY,  because get_filter does not accessible inside it.
  • Below is the screen of method ‘ConsumeRESTSet_GET_ENTITYSET
  • And ABAP code written inside method ‘ConsumeRESTSet_GET_ENTITYSET‘ is as follows:
  • method CONSUMERESTSET_GET_ENTITYSET.
    
    DATA: lt_filters            TYPE /iwbep/t_mgw_select_option,
          ls_filter             TYPE /iwbep/s_mgw_select_option,
          ls_so                 TYPE /iwbep/s_cod_select_option,
          LS_CONSUMERESTSET     TYPE ZCL_ZTEST_ODATA_MPC=>TS_CONSUMEREST.
    
    DATA: lv_RestSrvUrl         TYPE STRING,                     "Var for Http REST Service Url
          lv_HTTP_CLIENT        TYPE REF TO IF_HTTP_CLIENT,      "Var for Rest Http Client     
          LV_REQUEST            TYPE STRING,
          LV_RESPONSE           TYPE STRING.
    
    
    * Initiating filter to Read input from EnitySet of ODataService
      lt_filters = io_tech_request_context->get_filter( )->get_filter_select_options( ).
    
    * Extract input from Property 'REQUEST' of EntitySet 'CONSUMERESTSet'
      Clear ls_filter.
      READ TABLE lt_filters WITH TABLE KEY property = 'REQUEST' INTO ls_filter.
      IF sy-subrc EQ 0.
        READ TABLE ls_filter-select_options INTO ls_so index 1.
        IF sy-subrc EQ 0.
          LV_REQUEST = ls_so-low.
        ENDIF.
      ENDIF.
    
    * REST Service URL
    lv_RestSrvUrl = 'http://<ServiceIP>:<Port>/<REST_Service_Path>'.
    
    *Steps to Call REST Service ===================================
    *STEP-1 : CREATE HTTP CLIENT
    CALL METHOD CL_HTTP_CLIENT=>CREATE_BY_URL
        EXPORTING
          URL                = lv_RestSrvUrl
        IMPORTING
          CLIENT             = lv_HTTP_CLIENT
        EXCEPTIONS
          ARGUMENT_NOT_FOUND = 1
          PLUGIN_NOT_ACTIVE  = 2
          INTERNAL_ERROR     = 3
          OTHERS             = 4
          .
    
    *STEP-2 :  AUTHENTICATE HTTP CLIENT
    CALL METHOD LV_HTTP_CLIENT->AUTHENTICATE
      EXPORTING
        USERNAME        = 'Service_user-id'
        PASSWORD        = 'Service_password'.
    
    *STEP-3 : Set headers for REST Service Request Call
    CALL METHOD lv_HTTP_CLIENT->REQUEST->SET_HEADER_FIELD
         EXPORTING NAME  = '~request_method'
                   VALUE = 'POST'.
    
     CALL METHOD lv_HTTP_CLIENT->REQUEST->SET_HEADER_FIELD
          EXPORTING NAME  = 'Content-Type'
                    VALUE = 'application/json; charset=utf-8'.
    
     CALL METHOD lv_HTTP_CLIENT->REQUEST->SET_HEADER_FIELD
          EXPORTING NAME  = 'Accept'
                    VALUE = 'application/json, text/html'.
    
    * STEP-3.1 : Attach Request Message
    CALL METHOD LV_HTTP_CLIENT->REQUEST->SET_CDATA
         EXPORTING DATA   = LV_REQUEST
                   OFFSET = 0.
    
    *STEP-4 :  SEND HTTP REQUEST
      CALL METHOD lv_HTTP_CLIENT->SEND
        EXCEPTIONS
          HTTP_COMMUNICATION_FAILURE = 1
          HTTP_INVALID_STATE         = 2.
    
    *STEP-5 :  GET HTTP RESPONSE
    CALL METHOD lv_HTTP_CLIENT->RECEIVE
          EXCEPTIONS
            HTTP_COMMUNICATION_FAILURE = 1
            HTTP_INVALID_STATE         = 2
            HTTP_PROCESSING_FAILED     = 3.
    
    *STEP-6 :  Extract Rest-Service-Response
    CLEAR LV_RESPONSE.
    LV_RESPONSE = lv_HTTP_CLIENT->response->get_cdata( ).
    
    *STEP-7 : Appending Rest-Service-Response to EntitySet of ODataService
    CLEAR LS_CONSUMERESTSET.
    LS_CONSUMERESTSET-REQUEST  = LV_REQUEST.  "Append Sent Request
    LS_CONSUMERESTSET-RESPONSE = LV_RESPONSE. "Append Receievd Response
    
    APPEND LS_CONSUMERESTSET TO ET_ENTITYSET.
    CLEAR LS_CONSUMERESTSET.
    
      endmethod.
  • Save and activate this method.

 

[3] Testing OData-Service which consumes REST-Service

  • Once above implementation gets completed, we can begin testing of service.
  • Note: before testing make sure, odataService is already registered, for same you can refer below blog of mine:
  • For testing in Fiori-server, go to t-code ‘/n/iwfnd/gw_client’ and below oDataService uri will be used to invoke REST service via oData.
    • here we are referring EntitySet ‘ConsumeRESTSet’
    • and in property ‘REQUEST’ we are passing JSON-Format input string which need to be send to REST-Service while calling
    • This JSON-Input-String is REST-Service’s input message format.
  • /sap/opu/odata/sap/ZTEST_ODATA_SRV/ConsumeRESTSet?$filter=REQUEST eq '[{"taskId":286079},{"taskId":287571}]'
  • select Protocol ‘HTTP’
  • select HTTP Method ‘GET’, here please note we are passing input in uri
  • Execute press ‘F8’ -> and in acknowledgement, we received REST-Service’s output in Property ‘RESPONSE’.
  • for reference Here ‘REQUEST’ property has same data which we supplied as an input.

[4] Debugging OData-Service which consumes REST-Service

  • Lets debug method ‘ConsumeRESTSet_GET_ENTITYSET’ to understand data flow.
  • Set external breakpoints
  • Execute/trigger oData Service from t-code ‘/n/iwfnd/gw_client’
  • Debugger enters in method, see first we have extracted input from property ‘REQUEST’ of ODataService’s EntitySet ‘ConsumeRESTSet’ into variable LV_REQUEST
  • Next debugger stops post calling REST-Service, where we can understand with help of variable data ‘LV_RESPONSE’ which has extracted output from REST-Service acknowledgement
  • The REST-Service’s output present in variable ‘LV_RESPONSE’. is been mapped/populated to oData-Service’ EntitySet ‘ConsumeRESTSet’ with help of structure ‘ET_ENTITYSET’ as shown in below screen
  • Thus we have understood how data is flowing from oDataService call to REST-Service call.

 

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply