Easy way to create APIs in SAP using standard classes
SAP provides multiple ways to interact or communicate with external systems using techniques like OData, RFCs, etc. In today’s IT era, APIs are the top priority when choosing communication mechanisms. SAP provides the standard class CL_REST_RESOURCE, which provides REST methods like GET, PUT, POST, DELETE, etc. In this blog, I have explained how to accept JSON from external systems and consume data in SAP.
Go to Tcode: SE24 and create a new class, ZCL_API_TEST. Click on the properties tab and add the superclass CL_REST_RESOURCE.
Redefine the POST method to get data outside SAP.
METHOD if_rest_resource~post. DATA:lr_data TYPE REF TO data. FIELD-SYMBOLS:<lt_table> TYPE STANDARD TABLE. TYPES: BEGIN OF ty_workarea, name(50), city(50), region(20), pin(6). TYPES: END OF ty_workarea. DATA: wa_data TYPE ty_workarea. DATA(lv_request_body) = mo_request->get_entity( )->get_string_data( ). /ui2/cl_json=>deserialize( EXPORTING json = lv_request_body CHANGING data = lr_data ). ASSIGN lr_data->* TO FIELD-SYMBOL(<ls_data>). ASSIGN COMPONENT 'TESTAPI' OF STRUCTURE <ls_data> TO FIELD-SYMBOL(<lt_table_ref>). ASSIGN <lt_table_ref>->* TO <lt_table>. LOOP AT <lt_table> ASSIGNING FIELD-SYMBOL(<ls_line>). ASSIGN <ls_line>->* TO FIELD-SYMBOL(<ls_line_value>). ASSIGN COMPONENT 'NAME' OF STRUCTURE <ls_line_value> TO FIELD-SYMBOL(<ld_key>). IF <ld_key> IS ASSIGNED. ASSIGN <ld_key>->* TO FIELD-SYMBOL(<ld_key_value>). wa_data-name = <ld_key_value>. ENDIF. ASSIGN COMPONENT 'CITY' OF STRUCTURE <ls_line_value> TO <ld_key>. IF <ld_key> IS ASSIGNED. ASSIGN <ld_key>->* TO <ld_key_value>. wa_data-city = <ld_key_value>. ENDIF. ASSIGN COMPONENT 'REGION' OF STRUCTURE <ls_line_value> TO <ld_key>. IF <ld_key> IS ASSIGNED. ASSIGN <ld_key>->* TO <ld_key_value>. wa_data-region = <ld_key_value>. ENDIF. ASSIGN COMPONENT 'PIN' OF STRUCTURE <ls_line_value> TO <ld_key>. IF <ld_key> IS ASSIGNED. ASSIGN <ld_key>->* TO <ld_key_value>. wa_data-pin = <ld_key_value>. ENDIF. ENDLOOP. ENDMETHOD.
Create the REST handler class ZCL_REST_TEST and provide the superclass name CL_REST_HTTP_HANDLER. Also, redefine the method GET_ROOT_HANDLER. This handler class will be used while creating SICF services. The main purpose of this handler class is to link the URL to the REST resource class.
As shown in the above snapshot, the template name is /ZAPI, and this root handler class will be linked to the ZCL_API_TEST class. In the API POST class, the POST method of the ZCL_API_TEST class will be called.
DATA(lo_router) = NEW cl_rest_router( ). lo_router->attach( iv_template = '/ZAPI' iv_handler_class = 'ZCL_API_TEST' ). ro_root_handler = lo_router.
Enter description of the service, go to handler list tab, and put class name as ZCL_REST_TEST.
Go back and activate the service.
Right-click on the ZAPI service and click on Test Service; you will get the URL. Just copy the URL and add ZAPI to the existing path.
Here, ZAPI is case sensitive.
By Passing Token Validation:
When we want to do a POST call, token generation is mandatory, which is achieved by performing a GET call and then putting the token in the POST call. This process of token validation can also be bypassed by redefining the HANDLE_CSRF_TOKEN method without writing any code.
Testing the API using POSTMAN:
Select POST call and enter the URL. Select basic authentication in the authorization tab and enter a username and password. In the body part, select “raw” and create JSON data.
In the above snapshot, we can see the wa_data work area contains all the data that is passed through JSON.
This approach is very efficient and straight-forward for understanding and implementation. This method of API implementation also overcomes the drawback of OData, which passes space-separated fields in JSON. Token bypassing or redefinition is also possible, which will ease the process of API calling.
I’m looking forward to hearing more about API creation using SAP standard classes. Feel free to comment and discuss.
Best regards, thanks for reading, and stay healthy.
Hi Abhijeet. Thanks for the blog. I have a question. Is it possible to consume these API's outside of the network. I tried this in the past but I had to be logged in to the VPN, to access the API's
This can be accomplished by making the system's IP address public and then securing the system by allowing only necessary traffic (the IP addresses of third-party systems) through the firewall. At the API level, the same can be restricted using a username and password.