Skip to Content
Technical Articles
Author's profile photo Arijit Dutta

Http call from ABAP and using the response based on request

Introduction:

This blog post will describe in detail how to call an external API directly into the ABAP system using API Key. (Background job to execute this code on daily basis. )

 

Requirement:

Step1 – To verify if the data is coming as expected

Jason – Request

 Jason – Response:

Response

Response

API Key – To fetch data from a source system into ABAP

Step 2 – The certificate needs to be installed in “SSL Server Standard”

SSL%20Certificate

SSL Certificate

Step 3 – ABAP Program

REPORT  ztrigger_send_alert_msg.

* Include for Global Data Declaration.
INCLUDE ztrigger_send_alert_msg_a_top.
* Include for Selection Screen Definition.
INCLUDE ztrigger_send_alert_msg_a_sel.
* Include for Subroutines of the Program..
INCLUDE ztrigger_send_alert_msg_a_f00.

START-OF-SELECTION.
**************************************
*Prepare URL for API Access
**************************************
PERFORM get_url.

**************************************
*Read API Key from TVARVC
**************************************
PERFORM read_api_key."Api key
**************************************
*prepare URL for connection
**************************************
READ TABLE gt_url INTO ls_url WITH KEY tdcompont =  c_thg_alert_mess_url.

CONCATENATE ls_url-zvr1 ls_url-zvr2 INTO lv_url.
**************************************
*Create HTTP Request
**************************************

CALL METHOD cl_http_client=>create_by_url
EXPORTING
url                = lv_url
IMPORTING
client             = http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active  = 2
internal_error     = 3
OTHERS             = 4.
*********************************
* set header fields
*********************************
PERFORM set_header_fields.

*  http_client->request->set_method( 'GET' ).
*********************************
* set json string for body
*********************************
PERFORM set_pack_body CHANGING ls_json.

lv_len = STRLEN( ls_json ).

**  *************xxx*************
**  **************************
**  **************************
*  DATA lv_payload_x TYPE xstring.
*  CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
*    EXPORTING
*      text   = ls_json
*    IMPORTING
*      buffer = lv_payload_x.
*
*  http_client->request->set_method( 'POST' ).
*  http_client->request->set_content_type( 'application/json' ).
*  http_client->request->set_data( lv_payload_x ).
*
**  **************************
**  **************************
**  **************xxx************

**********************************
* message body
**********************************
CALL METHOD http_client->request->set_cdata
EXPORTING
data   = ls_json
offset = 0
length = lv_len.
********************************
* Send request
********************************
CALL METHOD http_client->send
EXCEPTIONS
http_communication_failure = 1
http_invalid_state         = 2.

IF sy-subrc <> 0.
MESSAGE 'Error while sending  HTTP request:' TYPE  'E'.             " connection error
ENDIF.
*
DATA: xstring_response TYPE xstring,
string_response  TYPE string.

*  CALL METHOD cl_http_utility=>escape_url
*    EXPORTING
*      unescaped = lv_url
*      OPTIONS   = 1
*    RECEIVING
*      escaped   = lv_url.

********************************
* Receive request
********************************

CALL METHOD http_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state         = 2
http_processing_failed     = 3.

IF sy-subrc <> 0.

http_client->response->get_status(
IMPORTING
code   = lv_ret_code
reason = lv_err_string
).
MESSAGE lv_err_string TYPE 'I'.
* Check for any response data
lv_response = http_client->response->get_cdata( ).

*   Write error to table
ls_zhd_error_log-vbeln      = p_aplid.
ls_zhd_error_log-type       = 'E'.
ls_zhd_error_log-id         = c_id.
ls_zhd_error_log-zdate      = sy-datum.
ls_zhd_error_log-ztime      = sy-uzeit.
ls_zhd_error_log-message    = lv_response.
ls_zhd_error_log-message_v1 = lv_ret_code.
ls_zhd_error_log-message_v2 = lv_err_string.
ls_zhd_error_log-message_v3 = sy-host.

INSERT into zhd_error_log values ls_zhd_error_log.

*****************Insert Alert_Audit
****************Data Mapping: Insert ALERT_AUDIT
ls_zalert_audit-appl_id = p_aplid.
ls_zalert_audit-alert_id = p_alrtid.
ls_zalert_audit-user_id = p_userid.
ls_zalert_audit-key_data = p_keyd.

CONCATENATE sy-datum sy-uzeit INTO lv_timestamp.
lv_short_time_stamp = lv_timestamp.

ls_zalert_audit-posting_timestp = lv_short_time_stamp."wa_zalert_subscripts-posting_timestp.
ls_zalert_audit-alert_action = c_action_f.
INSERT into zalert_audit values ls_zalert_audit.

MESSAGE 'Error While receiving HTTP request:' TYPE 'E'.             " connection error
ENDIF.

*  *****************************
*  *****************************
*  xstring_response = http_client->response->get_data( ).
*  string_response = cl_abap_codepage=>convert_from( xstring_response ).

*  *****************************
*  *****************************

http_client->response->get_status(
IMPORTING
code   = lv_http_code
reason = lv_code_reason
).
lv_code = lv_http_code.

CONCATENATE lv_code lv_code_reason INTO lv_reason SEPARATED BY space.

MESSAGE lv_reason TYPE 'I'.

lv_response = http_client->response->get_cdata( ).
*  *   Write error to table
ls_zhd_error_log-vbeln      = p_aplid.
ls_zhd_error_log-type       = 'S'.
ls_zhd_error_log-id         = c_id.
ls_zhd_error_log-zdate      = sy-datum.
ls_zhd_error_log-ztime      = sy-uzeit.
ls_zhd_error_log-message    = lv_response.
ls_zhd_error_log-message_v1 = lv_ret_code.
ls_zhd_error_log-message_v2 = lv_err_string.
ls_zhd_error_log-message_v3 = sy-host.

*****************Insert Alert_Audit
****************Data Mapping: Insert ALERT_AUDIT
ls_zalert_audit-appl_id = p_aplid.
ls_zalert_audit-alert_id = p_alrtid.
ls_zalert_audit-user_id = p_userid.
ls_zalert_audit-key_data = p_keyd.

CONCATENATE sy-datum sy-uzeit INTO lv_timestamp.
lv_short_time_stamp = lv_timestamp.

ls_zalert_audit-posting_timestp = lv_short_time_stamp.
ls_zalert_audit-alert_action = c_action_s.
INSERT into zalert_audit values ls_zalert_audit.

*&---------------------------------------------------------------------*
*&  Include           ZTRIGGER_SEND_ALERT_MSG_A_TOP
*&---------------------------------------------------------------------*
* Tables
DATA: gt_url TYPE TABLE OF zctrl_functions.

DATA: http_client TYPE REF TO if_http_client,
gs_api_key TYPE string,
lv_status_code TYPE i,
lv_status_text TYPE string,
lv_response TYPE string,
lv_url TYPE string,
ls_url LIKE zctrl_functions,
ls_api_key TYPE string,
ls_json     TYPE string,
lv_len      TYPE i,
gv_retry TYPE i,
gv_retry_success(1) TYPE c,
gv_wait TYPE i,
gv_logsave(1) TYPE c,
lv_err_string TYPE string,
lv_ret_code   TYPE sy-subrc,
lv_http_code TYPE sy-subrc,
lv_code TYPE string,
lv_code_reason TYPE string,
lv_reason TYPE string,
ls_zalert_audit TYPE zalert_audit,
ls_zhd_error_log TYPE zhd_error_log,
lv_timestamp TYPE char20,
lv_short_time_stamp TYPE timestamp.

CONSTANTS:   c_url(3) TYPE c VALUE 'URL',
c_thg_alert_mess_url(20)  TYPE c VALUE 'THG_ALERT_MESS_URL',
c_thg_alert_mess_url_key(25) TYPE c VALUE 'THG_ALERT_MESS_URL_KEY',
c_blank                         TYPE c VALUE ' ',
c_post                           TYPE string VALUE 'POST',
c_action_s                      TYPE string VALUE 'SENT SUCCESS',
c_action_f                      TYPE string VALUE 'SENT FAILURE',
c_id                            TYPE string VALUE 'Trigger Send Alert Message'.




*&---------------------------------------------------------------------*
*&  Include           ZTRIGGER_SEND_ALERT_MSG_A_SEL
*&---------------------------------------------------------------------*

* Block 1: SELECTION CRITERIA
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.

PARAMETERS : p_aplid  TYPE char40.
PARAMETERS : p_alrtid  TYPE char40.
PARAMETERS : p_userid  TYPE char80.
PARAMETERS : p_keyd  TYPE char80.
PARAMETERS : p_msgid  TYPE char80.
PARAMETERS : p_medtyp  TYPE char80.

SELECTION-SCREEN END OF BLOCK b1.




*&---------------------------------------------------------------------*
*&  Include           ZTRIGGER_SEND_ALERT_MSG_A_F00
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  GET_URL
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_GT_URL  text
*----------------------------------------------------------------------*
FORM get_url.

CLEAR gt_url.

SELECT * FROM zctrl_functions  INTO TABLE  gt_url
WHERE  progname = sy-repid
AND  zpara    = c_url.

IF sy-subrc NE 0.
MESSAGE 'Unable to get Sorted URLs for Connection.' TYPE 'E'. " No Sorted URLs
ENDIF.
*

ENDFORM.                    " GET_URL
*&---------------------------------------------------------------------*
*&      Form  READ_API_KEY
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_GS_API_KEY  text
*----------------------------------------------------------------------*
FORM read_api_key.

SELECT SINGLE low FROM tvarvc INTO ls_api_key WHERE name = c_thg_alert_mess_url_key.

ENDFORM.                    " READ_API_KEY
**&---------------------------------------------------------------------*
**&      Form  SET_HEADER_FIELDS
**&---------------------------------------------------------------------*
**       text
**----------------------------------------------------------------------*
**      -->P_P_API_KEY  text
**      -->P_C_BLANK  text
**----------------------------------------------------------------------*
FORM set_header_fields.

* Setup request header
CALL METHOD http_client->request->set_header_field
EXPORTING
name  = 'Ocp-Apim-Subscription-Key'
value = ls_api_key.

* Setup request header
CALL METHOD http_client->request->set_header_field
EXPORTING
name  = 'Accept'
value = 'application/json'.
*
* Setup request header
CALL METHOD http_client->request->set_header_field
EXPORTING
name  = 'Content-Type'
*      value = 'application/json'.
value = 'application/json ;charset=UTF-8'.

* Setup request header
CALL METHOD http_client->request->set_header_field
EXPORTING
name  = '~request_method'
value = c_post.

ENDFORM.                    " SET_HEADER_FIELDS
**&---------------------------------------------------------------------*
**&      Form  SET_PACK_BODY
**&---------------------------------------------------------------------*
**       text
**----------------------------------------------------------------------*
**  -->  p1        text
**  <--  p2        text
**----------------------------------------------------------------------*
FORM set_pack_body CHANGING p_json.

p_json = '{'.
CONCATENATE: p_json '"request": {' INTO p_json.

CALL FUNCTION 'CONVERSION_EXIT_MATN1_OUTPUT'
EXPORTING
input  = p_keyd
IMPORTING
output = p_keyd.

* exmp: CONCATENATE: p_json '"Width":' ls_width ',' INTO p_json SEPARATED BY space.

CONCATENATE: p_json '"productId":' p_keyd ',' INTO p_json.
CONCATENATE: p_json '"alertId": "'p_alrtid'" ,' INTO p_json SEPARATED BY space.
CONCATENATE: p_json '"recipients": [' INTO p_json SEPARATED BY space.
CONCATENATE: p_json '{' INTO p_json SEPARATED BY space.

TRANSLATE p_userid TO LOWER CASE.
CONCATENATE: p_json '"emailAddress": "'p_userid'"' INTO p_json SEPARATED BY space.
CONCATENATE: p_json '}' INTO p_json SEPARATED BY space.
CONCATENATE: p_json ']' INTO p_json SEPARATED BY space.
CONCATENATE: p_json '}' INTO p_json SEPARATED BY space.
CONCATENATE: p_json '}' INTO p_json SEPARATED BY space.
CONDENSE p_json NO-GAPS.

ENDFORM.                    " SET_PACK_BODY
**&---------------------------------------------------------------------*
**&      Form  HTTP_RECEIVE_RETRY
**&---------------------------------------------------------------------*
**       text
**----------------------------------------------------------------------*
**  -->  p1        text
**  <--  p2        text
**----------------------------------------------------------------------*
FORM http_receive_retry .
CLEAR gv_retry_success.

* Retry HTTP receive for the configured number of times
DO gv_retry TIMES.

*   Check for wait
IF NOT gv_wait = space.
WAIT UP TO gv_wait SECONDS.
ENDIF.

*   HTTP receive
CALL METHOD http_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state         = 2
http_processing_failed     = 3.

*   If it worked, set success flag and exit
IF sy-subrc = 0.
gv_retry_success = 'X'.
EXIT.
ENDIF.

ENDDO.
ENDFORM.                    " HTTP_RECEIVE_RETRY
**&---------------------------------------------------------------------*
**&      Form  SAVE_HTTP_STATUS
**&---------------------------------------------------------------------*
**       text
**----------------------------------------------------------------------*
**      -->P_C_SORTED_PACK_ORDER  text
**----------------------------------------------------------------------*
FORM save_http_status  USING    p_c_sorted_pack_order.
DATA : lv_err_string TYPE string,
lv_ret_code   TYPE sy-subrc,
ls_zhd_error_log LIKE zhd_error_log,
lv_response TYPE string.

* Only continue if logging is turned on
CHECK gv_logsave = 'X'.

* HTTP Status
http_client->response->get_status(
IMPORTING
code   = lv_ret_code
reason = lv_err_string
).

* Check for any response data
lv_response = http_client->response->get_cdata( ).

* Ensure there is something to log
IF NOT lv_ret_code IS INITIAL OR NOT lv_err_string IS INITIAL
OR NOT lv_response IS INITIAL.

CLEAR ls_zhd_error_log.

*   Write error to table
ls_zhd_error_log-vbeln      = p_aplid.
ls_zhd_error_log-type       = 'E'.
*    ls_zhd_error_log-id         = p_id.
ls_zhd_error_log-zdate      = sy-datum.
ls_zhd_error_log-ztime      = sy-uzeit.
ls_zhd_error_log-message    = lv_response.
ls_zhd_error_log-message_v1 = lv_ret_code.
ls_zhd_error_log-message_v2 = lv_err_string.
ls_zhd_error_log-message_v3 = sy-host.              " DECK924012

INSERT into zhd_error_log values ls_zhd_error_log.

ENDIF.
ENDFORM.                    " SAVE_HTTP_STATUS

Conclusion:

It is a direct call API from ABAP. Hope this is useful to you. Thanks

Assigned Tags

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

      You might beautify your blog post by using the CODE button, e.g.

      REPORT  ztrigger_send_alert_msg.
      
      * Include for Global Data Declaration.
      INCLUDE ztrigger_send_alert_msg_a_top.
      Author's profile photo Prakhar Alok
      Prakhar Alok

      Jason, really ?

      Please give some examples of external systems where ABAP might need to make a direct API call, like Coupa or any encryption server. Your readers would get much more context that way. Or maybe the business requirement you came across where you made the API call.

      Also the code example given, please give code snippets using ABAP >7.4 syntax/features as its pretty much a norm these days.