Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
dilipkkp2412
Contributor

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:


    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.


 
9 Comments
Labels in this area