In order to easily call and process APIs in ABAP, there is a very useful and easy-to-use object repository provided by SAP: the Service Consumption Model 2.
This Service Consumption Model automatically creates a proxy that can then be called via a class. This proxy makes it easy to manage API return structures, call parameters (GET, POST, DELETE, PUT, PACTH), different services, etc…
We’ll look in detail at how to generate this proxy and how to use it. We’ll also see how it’s easier to use it than to manage API processing manually in ABAP code.
For this example, we’ll use the Northwind API.
Proxy creation via Service Consumption Model
1/ Go to New > Other Repository Object >Service Consumption Model
2/ Naming the Service Consumption Model
3/ Name the generated proxy and forunir the EDMX file containing API metadata: https://services.odata.org/v4/northwind/northwind.svc/$metadata
4/ This will create all the objects needed for processing to call the API and these services
5/ It is possible to add an Etag, which is not done here
6/ Finally, the Service Consumption model has been created and now offers templates for calling each endpoint available in the API with each available method (GET, POST, etc.).
As you can see, these templates call the previously generated proxy.
Note: As this functionality is only available on BTP, ABAP Environment and S/4 Hana Public Cloud, there is a workaround to use the Service Consumption Model for S/4 Hana On-Premise and Private Cloud using BTP ABAP Environment, Trial Edition.
Sample call
In our case, we’ve decided to call the “Products” service.
We copy and paste the proposed template with 2 changes.
- As no authentication is required for this API, we create the http destination directly via cl_http_destination_provider=>create_by_url
DATA(lo_destination) = cl_http_destination_provider=>create_by_url( 'https://services.odata.org' ).
lo_http_client = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).
If an authentication system has been set up, I recommend using a communication arrangement, whose documentation can be found below:
Note: for On-Premise or Private Cloud systems, we recommend using an SM59 destination.
- When creating the proxy, we specify the path to call the API (be careful not to specify the entity, in this case “/Products”, which will be called since it will be managed later when the API is called with the proxy).
lo_client_proxy = /iwbep/cl_cp_factory_remote=>create_v4_remote_proxy(
EXPORTING
is_proxy_model_key = VALUE #( repository_id = 'DEFAULT'
proxy_model_id = 'ZTEST_NORTHWIND'
proxy_model_version = '0001' )
io_http_client = lo_http_client
iv_relative_service_root = '/v4/northwind/northwind.svc' ).
Code explanation
1/ Create the HTTP destination with the URL of the target system and create the proxy for the desired service
DATA(lo_destination) = cl_http_destination_provider=>create_by_url( 'https://services.odata.org' ).
lo_http_client = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).
lo_client_proxy = /iwbep/cl_cp_factory_remote=>create_v4_remote_proxy(
EXPORTING
is_proxy_model_key = VALUE #( repository_id = 'DEFAULT'
proxy_model_id = 'ZTEST_NORTHWIND'
proxy_model_version = '0001' )
io_http_client = lo_http_client
iv_relative_service_root = '/v4/northwind/northwind.svc' ).
ASSERT lo_http_client IS BOUND.
2/ Choose the product you wish to select and specify the entity to be called in the proxy (here /Products, specifying “PRODUCTS”).
" Set entity key
ls_entity_key = VALUE #(
product_id = 1 ).
" Navigate to the resource
lo_resource = lo_client_proxy->create_resource_for_entity_set( 'PRODUCTS' )->navigate_with_key( ls_entity_key ).
3/ Execute API GET call to /Products service for product_id = 1
lo_response = lo_resource->create_request_for_read( )->execute( ).
lo_response->get_business_data( IMPORTING es_business_data = ls_business_data ).
The API return data will be stored in the ls_business_data variable, of type ls_business_data TYPE ztest_northwind=>tys_alphabetical_list_of_produ (type automatically created by the Service Consumption Model).
When debugging this class, we see the return of the API call
This corresponds to the data obtained when the following URL is called up in the browser: https://services.odata.org/v4/northwind/northwind.svc/Products(1)
Complete code
CLASS ztest_crt_proxy DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ztest_crt_proxy IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA:
ls_entity_key TYPE ztest_northwind=>tys_alphabetical_list_of_produ,
ls_business_data TYPE ztest_northwind=>tys_alphabetical_list_of_produ,
lo_http_client TYPE REF TO if_web_http_client,
lo_resource TYPE REF TO /iwbep/if_cp_resource_entity,
lo_client_proxy TYPE REF TO /iwbep/if_cp_client_proxy,
lo_request TYPE REF TO /iwbep/if_cp_request_read,
lo_response TYPE REF TO /iwbep/if_cp_response_read.
TRY.
" Create http client
*DATA(lo_destination) = cl_http_destination_provider=>create_by_comm_arrangement(
* comm_scenario = '<Comm Scenario>'
* comm_system_id = '<Comm System Id>'
* service_id = '<Service Id>' ).
*lo_http_client = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).
DATA(lo_destination) = cl_http_destination_provider=>create_by_url( 'https://services.odata.org' ).
lo_http_client = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).
lo_client_proxy = /iwbep/cl_cp_factory_remote=>create_v4_remote_proxy(
EXPORTING
is_proxy_model_key = VALUE #( repository_id = 'DEFAULT'
proxy_model_id = 'ZTEST_NORTHWIND'
proxy_model_version = '0001' )
io_http_client = lo_http_client
iv_relative_service_root = '/v4/northwind/northwind.svc' ).
ASSERT lo_http_client IS BOUND.
" Set entity key
ls_entity_key = VALUE #(
product_id = 1 ).
" Navigate to the resource
lo_resource = lo_client_proxy->create_resource_for_entity_set( 'PRODUCTS' )->navigate_with_key( ls_entity_key ).
" Execute the request and retrieve the business data
lo_response = lo_resource->create_request_for_read( )->execute( ).
lo_response->get_business_data( IMPORTING es_business_data = ls_business_data ).
CATCH /iwbep/cx_cp_remote INTO DATA(lx_remote).
" Handle remote Exception
" It contains details about the problems of your http(s) connection
CATCH /iwbep/cx_gateway INTO DATA(lx_gateway).
" Handle Exception
CATCH cx_web_http_client_error INTO DATA(lx_web_http_client_error).
" Handle Exception
RAISE SHORTDUMP lx_web_http_client_error.
ENDTRY.
ENDMETHOD.
ENDCLASS.
Conclusion
Using the Service Consumption Model, calls to external APIs are greatly simplified, since a proxy is automatically created to easily manage calls and their returns.
This proxy can be used to make API calls in ABAP classes or in RAP objects with custom CDS Entities and expose them in a Fiori tile, for example.