on 2022 Jan 21 7:48 PM
Hello SAP Gurus,
Am Trying to build a generic ABAP function module to call external APIs. The function module accepts the method name and the parameters/values.
The below code works fine and the response is displayed when the API is called from a ABAP program.
But, the same code doesn't work well when called from my function module. Am not able to figure out what is going wrong.
The response says: {"hint": if a new function is created in the database with this name and parameters, try reloading the schema cache. Could not find the public.<method>(<parameters>) function in the schema cache}.
* HTTP Client Abstraction
DATA lo_client TYPE REF TO if_http_client.
* Data variables for storing response in xstring and string
DATA : lv_xstring TYPE xstring,
lv_string TYPE string,
lv_input TYPE string,
lv_value TYPE string,
lt_records TYPE STANDARD TABLE OF ty_recs,
lw_records TYPE ty_recs,
lw_inputs LIKE LINE OF api_inputs.
* Constants
CONSTANTS: lc_url TYPE string VALUE 'http://api.worldweatheronline.com/',
lc_quote(1) TYPE c VALUE '''',
lc_key TYPE string VALUE 'Bearer <key>'. " Authorization key
CLEAR : lv_xstring, lv_string.
* Pass the URL to get Data
TRANSLATE api_method TO LOWER CASE.
CONCATENATE lc_url api_method INTO lv_string.
* Creation of New IF_HTTP_Client Object
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = lv_string
IMPORTING
client = lo_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
pse_not_found = 4
pse_not_distrib = 5
pse_errors = 6
OTHERS = 7.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
* Set the required properties
lo_client->propertytype_logon_popup = lo_client->co_disabled.
CALL METHOD lo_client->request->set_header_field
EXPORTING
name = '~request_method'
value = 'POST'.
CALL METHOD lo_client->request->set_header_field
EXPORTING
name = 'content-type'
value = 'application/x-www-form-urlencoded'.
CALL METHOD lo_client->request->set_header_field
EXPORTING
name = 'Authorization'
value = lc_key.
* Build the HTTP request body from the Input Parameters
IF NOT api_inputs[] IS INITIAL.
LOOP AT api_inputs INTO lw_inputs.
CLEAR: lv_input, lv_value.
TRANSLATE lw_inputs-field_name TO LOWER CASE.
CONCATENATE lc_quote lw_inputs-field_name lc_quote INTO lv_input.
CONDENSE lv_input NO-GAPS.
TRANSLATE lw_inputs-field_value TO LOWER CASE.
CONCATENATE lc_quote lw_inputs-field_value lc_quote INTO lv_value.
CONDENSE lv_value NO-GAPS.
CALL METHOD lo_client->request->set_form_field
EXPORTING
name = lv_input
value = lv_value.
ENDLOOP.
ENDIF.
* Structure of HTTP Connection and Dispatch of Data
CALL METHOD lo_client->send
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 4.
* Receipt of HTTP Response
CALL METHOD lo_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 4.
IF sy-subrc IS NOT INITIAL.
* Handle errors
DATA: subrc TYPE sysubrc,
errortext TYPE string.
CALL METHOD lo_client->get_last_error
IMPORTING
code = subrc
message = errortext.
EXIT.
ENDIF.
* Return the HTTP body of this entity as binary data
DATA(lv_string2) = lo_client->response->get_cdata( ).
* Displays Response
CALL METHOD cl_abap_browser=>show_html
EXPORTING
html_string = lv_string2
dialog = abap_true.
Regards,
Rajasekhar
Help others by sharing your knowledge.
AnswerRequest clarification before answering.
Hi Guys,
Sorry Its not relevant for the question, But I'm also doing the same created a program to consume ARIBA API. The point that I stuck is that I need to instantiate a template using ABAP in ARIBA, I can able to do it successfully using Postman by sending body in json format, but not no clue how to send the body through ABAP. Please help me I'm in desperate to get solution.
Below are the other parameters I have written. Code between ******** and ******** is working perfectly, then for the instanciation of template I was not able to. If you scroll down in the code you will see an area of code it shows as blow where i wanted to send the body for the template.
--------------------------------> This where I need send the body as shown above screen shot.
*&---------------------------------------------------------------------*
*& Report YMRA_ARIBA_API1
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT YMRA_ARIBA_API1.
DATA: lv_url TYPE string,
lv_encod TYPE string,
lv_cred TYPE string,
lv_token_url TYPE string,
lr_http_cl TYPE REF TO if_http_client.
* Below is the ARIBA End point URL which will point to ARIBA API
lv_url = 'END POINT URL TO CALL THE VIEW'.
lv_token_url = 'TOKEN URL'." This is the Token URL to generate OAUTH Token
lv_cred = 'COMBO OF OAUTH ID &SECRET'. " Combo of OAUTH Client ID & Client Secret
*************************************************************************************
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = lv_token_url " OAUTH Token URL
IMPORTING
client = lr_http_cl. " Instance of http client for OAUTH
* To ping the ARIBA API using post menthod we need pass info via header Field. below is the post Method to get access Token
CALL METHOD lr_http_cl->request->set_header_field
EXPORTING
name = '~request_method'
value = 'POST'. "
DATA: utility TYPE REF TO cl_http_utility.
CREATE OBJECT utility.
* Below we fill variables for the header of post method encoded value for Authorization
CALL METHOD utility->encode_base64
EXPORTING
unencoded = lv_cred
RECEIVING
encoded = lv_encod.
lv_encod = |Basic { lv_encod }|. " Encoded value with BASIC constant,Fill Header filed of Authorization
WRITE: lv_encod.
* Pass Header field of Authorization
CALL METHOD lr_http_cl->request->set_header_field
EXPORTING
name = 'Authorization' " Header Field name
value = lv_encod. " Header Field value
* Pass Header field of Content-Type
CALL METHOD lr_http_cl->request->set_header_field
EXPORTING
name = 'Content-Type'" Header Field name
value = 'application/x-www-form-urlencoded'." Header Field value
lr_http_cl->request->set_form_field(
EXPORTING
name = 'grant_type' " Name of form field
value = 'client_credentials'). " Form field value
* Send above info to ARIBA check the status
CALL METHOD lr_http_cl->send
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2.
*Get return message from ARIBA and check the status
CALL METHOD lr_http_cl->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3.
* DO something with return
DATA: http_status_code TYPE i,
status_text TYPE string.
CALL METHOD lr_http_cl->response->get_status
IMPORTING
code = http_status_code
reason = status_text.
WRITE: / 'HTTP_STATUS_CODE = ',
http_status_code,
/ 'STATUS_TEXT = ',
status_text
.
DATA lv_result TYPE string.
* Below method gives us the access token and Refresh Token in JSON Format
CALL METHOD lr_http_cl->response->get_cdata
RECEIVING
data = lv_result.
WRITE:/ lv_result.
TYPES: BEGIN OF ty_token,
access_token TYPE string,
token_type TYPE string,
expires_in TYPE int4,
END OF ty_token.
DATA ms_token TYPE ty_token.
* Below is the call to converrt JSON to ABAP format
DATA(lo_json_converter) = cl_swf_cp_json=>new(
it_name_mapping = VALUE #(
( abap = 'access_token' json = 'access_token' )
( abap = 'token_type' json = 'token_type' )
( abap = 'expires_in' json = 'expires_in' )
)
).
lo_json_converter->deserialize( " Deserialze JSON data
EXPORTING
iv_context = lv_result
IMPORTING
data = ms_token
).
lr_http_cl->close( ).
***********************************************************************************
DATA: lv_bearer_token TYPE string.
CONCATENATE 'Bearer' ms_token-access_token INTO lv_bearer_token SEPARATED BY space. " get Bearer Token
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = lv_url " Pass ARIBA End point URL
IMPORTING
client = lr_http_cl. " Get http instance
CALL METHOD lr_http_cl->request->set_header_field " Calling a Get method to get data
EXPORTING
name = '~request_method'
value = 'GET'.
* Filling Authorization Header Field
CALL METHOD lr_http_cl->request->set_header_field
EXPORTING
name = 'Authorization'
value = lv_bearer_token.
* Filling API Key Header Field
CALL METHOD lr_http_cl->request->set_header_field
EXPORTING
name = 'apiKey'
value = 'avy8elMWxbz9LjRBfIXmwGw0WSDDXKDS'.
* Filling Form Field for Realm
lr_http_cl->request->set_form_field(
EXPORTING
name = 'realm' " Name of form field
value = 'wcm-1-T'). " Form field value
--------------------------------> This where I need send the body as shown above screen shot.
* Send the data to ARIBA
CALL METHOD lr_http_cl->send
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2.
*Get return
CALL METHOD lr_http_cl->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3.
* DO something with return
CALL METHOD lr_http_cl->response->get_status
IMPORTING
code = http_status_code
reason = status_text.
WRITE: / 'HTTP_STATUS_CODE = ',
http_status_code,
/ 'STATUS_TEXT = ',
status_text
.
DATA: lv_response TYPE string.
* Get the ARIBA API Data in JSON format
CALL METHOD lr_http_cl->response->get_cdata
RECEIVING
data = lv_response.
WRITE: / 'Final API Response : ',
lv_response.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
52 | |
8 | |
5 | |
5 | |
5 | |
5 | |
5 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.