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: 
younmazz
Participant
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

Define GR_JSON_SERIALIZER  Type Ref To /UI2/CL_JSON_SERIALIZER

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

 
Open HTTP client 

    cl_http_client=>create_by_url(
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
lr_client->request->set_header_field(
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 ).
*POST
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
ELSE.
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'.
ENDIF.
ls_bapiret2-message_v1 = <fs_l_jsonbody>-docid.
APPEND ls_bapiret2 TO rt_messages.
CLEAR ls_bapiret2.
ENDLOOP.

 
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  


 

 

Conclusion

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.   

 

 

 
Labels in this area