Skip to Content
Technical Articles
Author's profile photo Hyung Jin Youn

How to consume RESTful Cloud API from SAP with JSON request – MS Dynamics

Development Requirement 

Switching from a conventional middleware to direct consumption of a RESTful API in Azure Cloud requires me to design and build a new SAP program .


Business scenario 

SAP Invoices are to be sent out to Microsoft Dynamics AX Cloud to create local invoices in AX. The invoices from SAP need to be stored in a staging storage in MSDAX before being converted to the local invoices.


Technical configurations – Prerequisite 

  1. Obviously, you need url of API endpoint
  2. Open Firewall – add the target endpoint of API to White List in your network
  3. Configuration of Certificate of API endpoint on Azure in STRUST – SAP Oss note 2333326
  4. API key and value of API (Apps) on Azure – Need to get them issued from the target system

How to get an open SSL certificate – > Please refer to SAP OSS Note  2333326 – Tutorial – “Establishing trust between SSL client and SSL server on AS ABAP


SAP development  

Define a deep structure and an internal table, Sub field “items” is refer to a Table Type for items


Fill in data to the internal table with header & line items data


Json serialization 

Simple you can use  /ui2/cl_json=>serialize( ) but my case I need to tag document numbers with json request to save the return log. I used /UI2/CL_JSON_SERIALIZER to give a little bit tweak


 METHOD conv_jsonformat.

FREE gt_str_json.                             <- table type of  ‘z???_json’  
DATA ls_rv_json TYPE z???_json.    <- Document number + Json string 

    FREE gt_str_json.
    DATA ls_rv_json TYPE zvim_s_docid_json.

    LOOP AT gt_str_abap ASSIGNING FIELD-SYMBOL(<fs_l_abap_str>).
      GET REFERENCE OF <fs_l_abap_str> INTO DATA(lref_table).
      DATA(lv_json_str) = gr_json_serializer->/ui2/if_serialize~serialize( lref_table  ).
      CONCATENATE  '{"' 'INVOICES' '"  : '  '['    lv_json_str ']'  '}'  INTO ls_rv_json-json .
      ls_rv_json-docid = <fs_l_abap_str>-docid.
      APPEND ls_rv_json TO gt_str_json.


Open HTTP client 
         EXPORTING   url = url_path "Endpoint URL 
         IMPORTING   client = DATA(lr_client)
         EXCEPTIONS  argument_not_found = 1
                     plugin_not_active  = 2
                     internal_error     = 3
                     OTHERS             = 4  ).


Add API key and value into the header of json request 

EXPORTING    name  = ‘????key???’     <- The name of API key 
                         value   = ‘value?????’ ).   <- The value of the API key 

* Pass Credential
        EXPORTING name  = apikey_pair-name
                  value = apikey_pair-value ).


Define Json format and method type 'Post' in this case  
* Declare Json format
    lr_client->request->set_content_type( if_rest_media_type=>gc_appl_json ).
    lr_client->request->set_method( if_http_request=>co_request_method_post ).


Send request
* Send body
    LOOP AT gt_str_json ASSIGNING FIELD-SYMBOL(<fs_l_jsonbody>).
      lr_client->request->set_cdata( <fs_l_jsonbody>-json ).
* Send
      lr_client->send(    EXCEPTIONS  http_communication_failure = 1
                                http_invalid_state         = 2
                                http_processing_failed     = 3
                                http_invalid_timeout       = 4
                                OTHERS                     = 5 ).

      lr_client->receive( EXCEPTIONS
                                http_communication_failure = 1
                                http_invalid_state         = 2
                                http_processing_failed     = 3
                                OTHERS                     = 4 ).
      IF sy-subrc <> 0.
        lr_client->get_last_error( IMPORTING code    = DATA(lv_errcode)
                                             message = DATA(lv_errmesg) ).
*       RAISE EXCEPTION TYPE zcx_ax MESSAGE e000 WITH lv_errmesg lv_errcode .
*        ls_bapiret2-message =  |{lv_errmesg}| &&  |{lv_errmesg}|.
        ls_bapiret2-message = lv_errmesg && '  ' && lv_errmesg.
        ls_bapiret2-type = 'E'.
* Build
        DATA(_rt_from_call) = lr_client->response->get_cdata( ).
        update_single_inv( <fs_l_jsonbody>-docid  ).
        ls_bapiret2-message = _rt_from_call.
        ls_bapiret2-type = 'S'.
      ls_bapiret2-message_v1 = <fs_l_jsonbody>-docid.
      APPEND ls_bapiret2 TO rt_messages.
      CLEAR  ls_bapiret2.


You can close HTTP client  CL_HTTP_CLIENT->CLOSE( ).  now 

body of Json request that used in the above code   

    "INVOICES": [
            "DOCID": "00000?????",
            "ITEM_COUNT": "00002",
            "BUKRS": "7??",
            "XBLNR": "T??????9",
            "BLDAT": "????-??-??",
            "LIFNR": "0000?????",
            "CREDIT_MEMO": " ",
            "EBELN": null,
            "BKTXT": null,
            "SGTXT_HEADER": null,
            "GROSS_AMOUNT": 1100.00,
            "VAT_AMOUNT": 100.00,
            "DATE_CREATED": "????-??-??",
            "ITEMS": [
                    "ITEMID": "00001",
                    "KOSTL": "000070?????",
                    "HKONT": "00000?????",
                    "PRCTR": null,
                    "SGTXT_ITEM": "LINE 1",
                    "MWSKZ": "P1",
                    "SHKZG": "S",
                    "WRBTR": 550.00,
                    "ZUONR": null
                    "ITEMID": "00002",
                    "KOSTL": "00007????",
                    "HKONT": "00000?????",
                    "PRCTR": null,
                    "SGTXT_ITEM": "LINE 2",
                    "MWSKZ": "P1",
                    "SHKZG": "S",
                    "WRBTR": 550.00,
                    "ZUONR": null

Unit Test

MS Dynamics AX Cloud  




It’s quite simple and concise logics as you can see and not much efforts required to build ABAP code for Json interface. There is no doubt that many useful methods in ABAP class  CL_HTTP_CLIENT & /ui2/cl_json will help making your codes simpler and self-explained pattern.   




Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.