Call an External API and Parse the Response (JSON or XML))
Call an external API SAP BTP ABAP Environment and parse the response (JSON or XML)
Overview
You will learn
- How to connect to an external RESTful API, in this case the Overpass street map service: http://overpass-api.de/, by creating the necessary communication artifacts
- How to work with HTTP requests in your ABAP code
- How to query the service
- How to parse the information in an ABAP class using either JSON and SAP’s XCO Library or using XML and a simple transformation
- How to create an executable class and display the output in the ABAP console This tutorial enables you to work with data from an external RESTful API in your ABAP applications. Throughout this tutorial, object names include the suffix
000. Always replace this with your group number or initials. > This tutorial was written for SAP BTP ABAP Environment. However, you should also be able to use it in SAP S/4HANA Cloud Environment in the same way.
Prerequisites
Prerequisites
- IMPORTANT: This tutorial cannot be completed on a trial account
- You have set up SAP Cloud Platform, ABAP Environment, for example by using the relevant booster: Using a Booster to Automate the Setup of the ABAP Environment
- Tutorial: Set up SAP BTP ABAP Environment and Create Your First Console Application, for a licensed user, steps 1-2
- You have assigned the following to your business user:
SAP_BR_DEVELOPER - You have also assigned the following to your business user:
SAP_BR_ADMINISTRATOR(Business Role) andSAP_CORE_BC_COM(Business Catalog) You need these to work with Communication Management in SAP Fiori Launchpad
Steps
In ABAP Development Tools (ADT), select your ABAP Cloud Project and choose New > ABAP Package from the context menu.
Enter the following and choose Next:
- Super-package: Your super-package, if you are using one
- Name =
Z_API_OVERPASS_000 - Description = Get map data using Overpass map service API
- Add to favorite packages = Yes
- Package type = Development

step1a-create-package Choose Create new transport request, enter a description, such as Get data from API Overpass, then choose Finish.

step1c-new-transport-request
Select your ABAP package and choose New > Other Repository Object from the context menu; then enter Outbound Service, then choose Next.
Enter the following and choose Next.
- Outbound service:
Z_API_OVERPASS_OB_000 - Description: Get data from Overpass map service
- Service type: HTTP Service

step2a-new-outbound-service - Outbound service:
Choose the transport request you just created, then choose Finish.
The outbound service appears.
Enter the Default Path Prefix
/api/interpreter.
step2b-outbound-service-default-path-prefix Choose Save (
Ctrl + S).
Again, choose New > Other Repository Object from the context menu; then enter Communication Scenario.

step3a-create-comm-scenario Enter the following and choose Next.
Name:
Z_API_OVERPASS_CSCEN_000Description: Communication Scenario: Get data from Overpass map service

step3c-comm-scen-adt-name-etc
Choose the transport request you just created, then choose Finish.
The communication scenario appears in a new editor. Ensure the following have been entered:
Communication Scenario Type: Customer Managed
Allowed Instances: One instance per client

step3d-comm-scen-new-editor
On the Outbound tab, ensure that the authentication method Unauthenticated ticked.
Add your outbound service, by choosing Add….

step3c-add-ob Choose Browse, choose your outbound service,
Z_API_OVERPASS_OB_000, then choose Finish.The suffix REST has added to the outbound service name automatically.

step3d-add-ob-service-to-comm-scen 
step3e-comm-scen-editor Finally, Save your communication scenario, then choose Publish Locally.
Now, you need to create the necessary communication artifacts in Fiori Launchpad, starting with the Communication System. This artifact specifies hostname and port of the targeted remote API.
In the Fiori Launchpad home page, choose Communication System, then choose New.

step4a-comm-system 
step4b-new-comm-system Enter the following and choose Create.
- System ID:
Z_OVERPASS_000_CSYS - System Name:
Z_OVERPASS_000_CSYS

step4b-new-comm-system-dialog - System ID:
Enter host name:
overpass-api.deUnder Users for Outbound Communication, enter the option None.

step4c-outbound-user-authent 
step4c-outbound-user-password-none 
step4e-users-ob-none Leave the other default settings as they are and choose Save.
A communication arrangement establishes a specific communication route by combining one communication scenario and one communication system.
Go back to the Fiori Launchpad home page and choose Communication Arrangement, then choose New.

step5a-new-comm-arr Browse to, then select your Communication Scenario,
Z_API_OVERPASS_CSCEN_000(created in ADT). The Communication Arrangement name is filled automatically.
step5c-select-comm-scen 
step5b-comm-arr-name-etc In the main editor, select the Communication System,
Z_OVERPASS_000_CSYS. The Service URL, port etc are filled automatically.
step5e-comm-arr-comm-sys 
step5f-comm-arr-defaults-filled Choose Save. You can now check the connection.

step5d-check-connection 
step5g-ping-successful
Now, create the Simple Transformation, which converts the XML data to ABAP data.
In the Project Explorer, select your package (from the previous tutorial) and choose New > Other ABAP Repository Object > Transformations > Transformation, then choose Next.

step6a-transformation-new Enter the following:
- Name:
Z_OVERPASS_XML_ST_000 - Description: Transform Overpass Map Data: XML-ABAP
- Template: Simple transformation

step6b-transformation-name-etc - Name:
Choose your transport request and choose Finish. A skeleton transformation appears in a new editor.
Copy the following code into the
<tt:transform...node:ABAP<tt:root name="osm"/> <tt:template> <osm tt:ref=".osm"> <tt:attribute name="version" value-ref="api_version"/> <tt:attribute name="generator" value-ref="api_generator"/> <note tt:value-ref="note"/> <meta tt:ref="metadata"> <tt:attribute name="osm_base" value-ref="osm_base"/> <tt:attribute name="areas" value-ref="osm_areas"/> </meta> <tt:loop ref="nodes"> <node> <tt:attribute name="id" value-ref="id"/> <tt:attribute name="lat" value-ref="latitude"/> <tt:attribute name="lon" value-ref="longitude"/> <tt:loop ref="tags"> <tag> <tt:attribute name="k" value-ref="property"/> <tt:attribute name="v" value-ref="value"/> </tag> </tt:loop> </node> </tt:loop> </osm> </tt:template>
step6c-transformation-code Check your syntax (
Ctrl+F2).Format (
Ctrl+F1), save (Ctrl+S) and activate (Ctrl+F3) your class.
If you are using JSON, skip this step, since, instead of an ABAP transformation, you use the XCO Library.
Now, you will create an ABAP class that will call your destination, and which you can run in the console.
Select your package and choose New > ABAP Class from the context menu.

step7a-create-class Enter the following for your class and choose Next. Remember to change
000to your group number.- Name:
ZCL_OVERPASS_XML_000 - Description: Get map data using Overpass + XML
- Interfaces:
IF_OO_ADT_CLASSRUN(using Add…)

step7b-name-class - Name:
Choose or create a transport request, then choose Finish.
The skeleton class is displayed in a new editor.

To be able to access the external service, you will:
Create an HTTP client that points to your communication scenario and service id
Configure and send an HTTP request. You configure the request using
lo_request->set_query( )including specifying whether the response should be XML or JSONConvert the response to ABAP structures
Output the response in the ABAP console
Catch any potential exceptions that may be thrown.
A sample of the raw XML output is available here: OverpassRawOutputXML.txt
Implement the method if_oo_adt_classrun~main by inserting the following code. Replace the 000 with your group number or initials.
```ABAP
" Get data using XML
METHOD if_oo_adt_classrun~main.
" Create HTTP client
TRY.
DATA(lo_destination) = cl_http_destination_provider=&gt;create_by_comm_arrangement(
comm_scenario = 'ZMDC_OVERPASS_CSCEN'
service_id = 'ZMDC_OVERPASS_OBS_REST'
).
DATA(lo_http_client) = cl_web_http_client_manager=&gt;create_by_http_destination( i_destination = lo_destination ).
DATA(lo_request) = lo_http_client-&gt;get_http_request( ).
&quot; Send request; store response in lv_xml_results
lo_request-&gt;set_query( query = 'data=area[name=&quot;Heidelberg&quot;];node[&quot;amenity&quot;=&quot;biergarten&quot;](area);out;' ).
DATA(lo_response) = lo_http_client-&gt;execute( i_method = if_web_http_client=&gt;get ).
DATA(lv_xml_results) = lo_response-&gt;get_text( ).
CATCH cx_root INTO DATA(lx_exception).
out-&gt;write( lx_exception-&gt;get_text( ) ).
ENDTRY.
" Create structures etc
TYPES:
BEGIN OF ts_tag,
property TYPE string,
value TYPE string,
END OF ts_tag,
BEGIN OF ts_node,
id TYPE string,
latitude TYPE string,
longitude TYPE string,
tags TYPE STANDARD TABLE OF ts_tag WITH EMPTY KEY,
END OF ts_node,
BEGIN OF ts_metadata,
osm_base TYPE string,
osm_areas TYPE string,
END OF ts_metadata,
BEGIN OF ts_osm,
api_version TYPE string,
api_generator TYPE string,
note TYPE string,
metadata TYPE ts_metadata,
nodes TYPE STANDARD TABLE OF ts_node WITH EMPTY KEY,
END OF ts_osm.
DATA ls_osm TYPE ts_osm.
TRY.
" transform response; store transformed response in structure osm
CALL TRANSFORMATION zmdc_osm_xml_st
SOURCE XML lv_xml_results
RESULT osm = ls_osm.
out-&gt;write( | Names of beer gardens in Heidelberg (Germany) found on OpenStreetMaps. | ).
out-&gt;write( | Data is obtained from the OSM API in XML format and read into ABAP using a simple transformation (ST). | ).
out-&gt;write( | Note: Not all locations have an associated name. | ).
out-&gt;write( | Generator: { ls_osm-api_generator } | ).
out-&gt;write( | ---------------------------------- | ).
&quot; Output data to console
DATA lv_index TYPE int4.
LOOP AT ls_osm-nodes ASSIGNING FIELD-SYMBOL(&lt;node&gt;).
lv_index = sy-tabix.
LOOP AT &lt;node&gt;-tags ASSIGNING FIELD-SYMBOL(&lt;tag&gt;).
IF &lt;tag&gt;-property = 'name'.
out-&gt;write( | Beer garden number { lv_index }: { &lt;tag&gt;-value } | ).
ENDIF.
ENDLOOP.
ENDLOOP.
out-&gt;write( | ---------------------------------- | ).
" catch any error
CATCH cx_root INTO DATA(lx_root).
out->write( lx_root->get_text( ) ).
ENDTRY.
ENDMETHOD.
Code</code></pre>
</div>
<div class="tab-panel" data-tab-panel="1" data-tab-name="JSON" hidden>
<p>To be able to access the external service, you must:</p>
<ol>
<li>
<p>Create an HTTP client that points to your communication scenario and service id</p>
</li>
<li>
<p>Configure and send an HTTP request. You configure the request using <code>lo_request->set_query( )</code> including specifying whether the response should be XML or JSON</p>
</li>
<li>
<p>Convert the response to ABAP structures</p>
</li>
<li>
<p>Output the response in the ABAP console</p>
</li>
<li>
<p>Catch any potential exceptions that may be thrown.</p>
</li>
</ol>
<p>A sample of the raw JSON output is available here:
<a href="https://raw.githubusercontent.com/sap-tutorials/abap-core-development/master/tutorials/abap-environment-external-api/OverpassRawOutputJSON.txt">OverpassRawOutputJSON.txt</a></p>
<p>Implement the method <strong><code>if_oo_adt_classrunmain</code></strong> by inserting the following code. Replace the <code>000</code> with your group number or initials.</p>
<pre><code>```ABAP
" Get data using JSON
METHOD if_oo_adt_classrunmain.
" Create HTTP client; send request
TRY.
DATA(lo_destination) = cl_http_destination_provider=>create_by_comm_arrangement(
comm_scenario = 'Z_OVERPASS_JSON_CS_000'
service_id = 'Z_API_OVERPASS_JSON_000_REST'
).
DATA(lo_http_client) = cl_web_http_client_manager=&gt;create_by_http_destination( i_destination = lo_destination ).
DATA(lo_request) = lo_http_client-&gt;get_http_request( ).
lo_request-&gt;set_query( query = 'data=[out:json];area[name=&quot;Heidelberg&quot;];node[&quot;amenity&quot;=&quot;biergarten&quot;](area);out;' ).
DATA(lo_response) = lo_http_client-&gt;execute( i_method = if_web_http_client=&gt;get ).
DATA(lv_json_results) = lo_response-&gt;get_text( ).
CATCH cx_root INTO DATA(lx_exception).
out-&gt;write( lx_exception-&gt;get_text( ) ).
ENDTRY.
" Create an ABAP structure to contain the data from the API
TYPES:
BEGIN OF ts_tags,
name TYPE string,
website TYPE string,
END OF ts_tags,
BEGIN OF ts_element,
type TYPE string,
id TYPE string,
lat TYPE string,
lon TYPE string,
tags TYPE ts_tags,
END OF ts_element,
BEGIN OF ts_osm3s,
timestamp_osm_base TYPE string,
timestamp_areas_base TYPE string,
copyright TYPE string,
END OF ts_osm3s,
BEGIN OF ts_osm,
version TYPE string,
generator TYPE string,
osm3s TYPE ts_osm3s,
elements TYPE STANDARD TABLE OF ts_element WITH EMPTY KEY,
END OF ts_osm.
DATA ls_osm TYPE ts_osm.
" Convert the data from JSON to ABAP using the XCO Library; output the data
TRY.
xco_cp_json=&gt;data-&gt;from_string( lv_json_results )-&gt;apply( VALUE #(
( xco_cp_json=&gt;transformation-&gt;pascal_case_to_underscore )
( xco_cp_json=&gt;transformation-&gt;boolean_to_abap_bool )
) )-&gt;write_to( REF #( ls_osm ) ).
out-&gt;write( | Names of beer gardens in Heidelberg (Germany) found on OpenStreetMaps. | ).
out-&gt;write( | Data is obtained from the OSM API in JSON format and read into ABAP using the XCO library. | ).
out-&gt;write( | Note: Not all locations have an associated name. | ).
out-&gt;write( | Generator: { ls_osm-generator } | ).
out-&gt;write( | ---------------------------------- | ).
LOOP AT ls_osm-elements ASSIGNING FIELD-SYMBOL(&lt;element&gt;).
out-&gt;write( | Beer garden number { sy-tabix }: { &lt;element&gt;-tags-name } | ).
ENDLOOP.
out-&gt;write( | ---------------------------------- | ).
&quot; catch any error
CATCH cx_root INTO DATA(lx_root).
out-&gt;write( lx_root-&gt;get_text( ) ).
ENDTRY.
ENDMETHOD.
Check your syntax (
Ctrl+F2).Format (
Ctrl+F1), save (Ctrl+S) and activate (Ctrl+F3) your class.
Run your class in the console (F9). The output should look something like this.


- SAP Help Portal: Communication Management: Outbound Communication
- SAP Help Portal: SAP ABAP Development User Guide: Tasks - Working with Transformations for XML
- ABAP Keyword Documentation: ABAP and XML โ Transformations for XML โ ST - Simple Transformations
- Overpass API by Example
- SAP Help Portal: XCO Library: JSON
- SAP Community blog post: Introducing the XCO Library Cloud Platform edition
- Overpass Tag Information, including keys, tags etc: Overpass Tag Info
Resources
Discussion
Share feedback on this tutorial or join the conversation in SAP Community.