Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
Naveen_n
Explorer

Title: CRUD Operation Using RESTful API in SAP 

Introduction: 

SAP (Systems, Applications, and Products in Data Processing) is a renowned enterprise resource planning (ERP) software and integrating RESTful APIs with SAP can significantly enhance its capabilities. In this blog, we will delve into the basics of CRUD operations in REST API within the SAP environment, exploring the fundamental concepts and demonstrating how to perform Create, Read, Update, and Delete operations seamlessly. 

Understanding CRUD Operations: 

CRUD operations form the core of database interactions and are crucial for any application's functionality. In a REST API context, CRUD corresponds to the following HTTP methods: 

  1. Create (POST): This method is used to add new data to the server. 
  1. Read (GET): Retrieve information from the server without modifying it. 
  1. Update (PUT): Modify existing data on the server. 
  1. Delete (DELETE): Remove data from the server. 

Setting Up SAP for REST API Integration: 

Before diving into CRUD operations, you need to ensure that your SAP environment is set up to support REST API integration. This may involve configuring SAP Gateway, enabling web services, and securing communication between SAP and your application. 

In this blog, we'll explore how to Perform CRUD operation from Restful API  

Generally REST describes a machine-to-machine interface. In Web development, REST allows content to be rendered when it is requested, often referred to as Dynamic Content. RESTful Dynamic content uses server-side rendering to generate a Web site and send the content to the requesting Web browser, which interprets the server’s code and renders the page in the user’s Web browser. 

PROCEDURE: - 

Here We have to create structure and table type for sales order line-item condition  

Naveen_n_0-1707457624832.png

Naveen_n_1-1707457624835.png

Here we have to create structure and table type for Sales order line item and  pass Deep component(Structure which includes a Table type).  

Naveen_n_2-1707457624839.png

Naveen_n_3-1707457624842.png

Here we have to create Structure for sales order header information and here we have to pass  Deep component(Structure which includes a Table type). 

Naveen_n_4-1707457624845.png

Naveen_n_5-1707457624849.png

In SE24 create a class for request provider and request handler class. 

Naveen_n_6-1707457624852.png

Naveen_n_7-1707457624855.png

GET OPERATION: - 

 

METHOD if_rest_resource~get. 
    DATA : ls_so    TYPE zna_ty_sales_order, 
            lv_result   TYPE string, 
            lv_vbeln TYPE vbeln. 
 
    DATA : ls_item_condition TYPE zna_ty_sales_ord_item_cond, 
            lt_item_condition TYPE STANDARD TABLE OF zna_ty_sales_ord_item_cond, 
            ls_item           TYPE zna_ty_sales_ord_item, 
            lt_item           TYPE STANDARD TABLE OF zna_ty_sales_ord_item. 
 
    "read the uri parameter 
     lv_vbeln = mo_request->get_uri_query_parameter( 
                  iv_name    = 'VBELN' 
*                 iv_encoded = abap_true 
                ). 
 
    IF lv_vbeln IS NOT INITIAL. 
      lv_vbeln = |{ lv_vbeln ALPHA = IN }|.                 . 
       " Select header data 
 
      select SINGLE * FROM vbak INTO @DATA(ls_vbak) WHERE vbeln = @lv_vbeln. 
         IF ls_vbak-vbeln IS NOT INITIAL. 
 
"select line item data 
SELECT * FROM vbap INTO TABLE @DATA(lt_vbap) WHERE vbeln = @ls_vbak-vbeln. 
 
  "select conditions 
   SELECT * FROM konv INTO TABLE @DATA(lt_konv) WHERE knumv = @ls_vbak-knumv. 
 
    "pass the data to structure 
 
    ls_so-VBELN  = ls_vbak-vbeln. 
     ls_so-KUNNR  = ls_vbak-kunnr. 
     ls_so-VKORG  = ls_vbak-vkorg. 
     ls_so-VTWEG  = ls_vbak-vtweg. 
     ls_so-SPART  = ls_vbak-spart. 
     ls_so-BSTNK  = ls_vbak-bstnk. 
     ls_so-BSTDK  = ls_vbak-bstdk. 
*   MESSAGE 
*    ITEMS 
 
    LOOP AT lt_vbap INTO DATA(ls_vbap). 
       clear ls_item. 
       MOVE-CORRESPONDING ls_vbap TO ls_item. 
 
 
      LOOP AT lt_konv INTO DATA(ls_konv) WHERE knumv = ls_vbak-knumv 
                                              and kposn = ls_vbap-posnr. 
 
        CLEAR ls_item_condition. 
 
       ls_item_condition-VBELN = ls_vbap-vbeln. 
        ls_item_condition-POSNR = ls_vbap-posnr. 
        ls_item_condition-KPOSN = ls_konv-kposn. 
        ls_item_condition-stunr = ls_konv-stunr. 
        ls_item_condition-KSCHL = ls_konv-kschl. 
        ls_item_condition-KWERT = ls_konv-kwert. 
 
       APPEND ls_item_condition TO lt_item_condition. 
 
CLEAR ls_konv. 
       ENDLOOP. 
 
      ls_item-item_condition[] = lt_item_condition[]. 
 
      APPEND ls_item TO lt_item. 
 
CLEAR : ls_vbap,lt_item_condition[]. 
     ENDLOOP. 
 
    ls_so-items[] = lt_item[]. 
 
    ELSE. 
       ls_so-message = 'Sales order does not exist'. 
       ENDIF. 
 
 
      ELSE. 
    ls_so-message = 'Kindly enter the sales order number'. 
     ENDIF. 
 
    /ui2/cl_json=>serialize( 
       EXPORTING 
         data             =    ls_so   
       RECEIVING 
         r_json           =  lv_result                 " JSON string 
     ). 
 
    mo_response->create_entity( )->set_string_data( iv_data = lv_result  ). 
 
    mo_response->set_header_field( 
       EXPORTING 
         iv_name  =    'content-Type'              " Header Name 
         iv_value =    'application/json'              " Header Value 
     ). 
  ENDMETHOD. 

 

Naveen_n_8-1707457624860.png

Naveen_n_9-1707457624863.png

Implement the request handler class method “GET_ROOT_HANDLER”  

 

method IF_REST_APPLICATION~GET_ROOT_HANDLER. 
   
     DATA(lv_router) = NEW cl_rest_router( ). 
     lv_router->attach( 
       EXPORTING 
         iv_template      = '/zna_so'                 " Unified Name for Resources 
         iv_handler_class =  ' ZCL_NA_REST_RESOURCE_EXT '                " Object Type Name 
*        it_parameter     =                  " Resource contructor parameters 
     ). 
 
    ro_root_handler = lv_router. 
 
  endmethod. 

 

 

In T-code:- SCIF, we have to create host and test the service. 

Naveen_n_10-1707457624865.png 

Naveen_n_11-1707457624867.png

Naveen_n_12-1707457624870.png

Naveen_n_13-1707457624873.png

In this we have to add Handler name and provide sales order number and click on enter. 

Naveen_n_14-1707457624874.png

We have to execute browser and postman tool also. 

Naveen_n_0-1707458669292.png

Naveen_n_2-1707459200565.png

 

 

Naveen_n_3-1707459266016.png

 

CREATE OPERATION(POST): - 

Here we are inserting the data into the sales order database table. 

 

method IF_REST_RESOURCE~POST. 
  DATA : lv_string1 type VBELN,                "string, 
             lv_string2 type string, 
             lv_response TYPE string, 
             ls_so TYPE zna_t_so. 
 
DATA(lv_entity) = mo_request->get_entity( ). 
  DATA(lv_responce1) = mo_response->create_entity( ). 
 
*Read string data i.e json 
  DATA(lv_json) = lv_entity->get_string_data( ). 
 
/ui2/cl_json=>deserialize( 
    EXPORTING 
      json             =   lv_json              " JSON string 
   
    CHANGING 
      data             =    ls_so             " Data to serialize 
  ). 
INSERT INTO zna_t_so VALUES ls_so. 
 
/ui2/cl_json=>serialize( 
    EXPORTING 
      data             =  ls_so                " Data to serialize 
   
    RECEIVING 
      r_json           =     lv_response             " JSON string 
  ). 
 
lv_responce1->set_string_data( iv_data = lv_response ). 
   endmethod. 

 

Naveen_n_18-1707457624880.png

Before doing post operation we can get csrf token from the postman tool and after getting token we can pass to value tab. 

Naveen_n_4-1707459360387.png

 

Naveen_n_5-1707459425009.png

 

In body section, we need to pass the record and click on send. 

Naveen_n_6-1707459590818.png

 

Here we get success code 200 output data will be successfully inserted. 

Naveen_n_7-1707459615766.png

 

Data will be inserted . 

Naveen_n_8-1707459687864.png

 

UPDATE OPERATION(PUT): - 

 

method IF_REST_RESOURCE~PUT. 
  DATA : lv_string1 type VBELN,                "string, 
             lv_string2 type string, 
             lv_response TYPE string, 
             ls_so TYPE zna_t_so. 
 
DATA(lv_entity) = mo_request->get_entity( ). 
  DATA(lv_responce1) = mo_response->create_entity( 
*                         iv_multipart = abap_false 
                      ). 
 
*Read string data i.e json 
  DATA(lv_data) = lv_entity->get_string_data( ). 
 
/ui2/cl_json=>deserialize( 
    EXPORTING 
      json             =   lv_data               " JSON string 
   
    CHANGING 
      data             =    ls_so             " Data to serialize 
  ). 
 
UPDATE ZNA_T_SO FROM ls_so. 
 
/ui2/cl_json=>serialize( 
    EXPORTING 
      data             =  ls_so                " Data to serialize 
   
    RECEIVING 
      r_json           =     lv_response             " JSON string 
  ). 
 
lv_responce1->set_string_data( iv_data = lv_response ). 
   endmethod. 

 

Naveen_n_24-1707457624885.png

We can change the field value and click on send. 

Naveen_n_9-1707459753787.png

 

BEFORE: - 

Naveen_n_26-1707457624887.png

AFTER: - 

Naveen_n_27-1707457624889.png

DELETE OPERATION: - 

 

METHOD if_rest_resource~delete. 
     DATA : lv_string1  TYPE vbeln,                "string, 
            lv_string2  TYPE string, 
            lv_response TYPE string, 
            ls_so       TYPE zna_t_so. 
 
    DATA(lv_entity) = mo_request->get_entity( ). 
     DATA(lv_responce1) = mo_response->create_entity( 
*                         iv_multipart = abap_false 
                         ). 
 
*Read string data i.e json 
     DATA(lv_data) = lv_entity->get_string_data( ). 
 
    /ui2/cl_json=>deserialize( 
        EXPORTING 
          json             =   lv_data               " JSON string 
   
        CHANGING 
          data             =    ls_so             " Data to serialize 
      ). 
 
 
 
    DELETE zna_t_so FROM ls_so. 
 
    /ui2/cl_json=>serialize( 
        EXPORTING 
          data             =  ls_so                " Data to serialize 
   
        RECEIVING 
          r_json           =     lv_response             " JSON string 
      ). 
 
    lv_responce1->set_string_data( iv_data = lv_response ). 
   ENDMETHOD. 

 

Naveen_n_28-1707457624890.png 

Here we delete the value 00000000003. 

Naveen_n_11-1707459967794.png

 

 

BEFORE DELETE: - 

Naveen_n_30-1707457624892.png

AFTER DELETE: - 

Naveen_n_31-1707457624893.png

 

1 Comment
Florian
Active Contributor

May I ask why you are trying to do the rest-service freestyle?

Firstly, I would nobody recommend using the Rest-Classes. Please try to use the Odata-Framework.

Next to it, I really encourage you to use the modern IDE Eclipse.

If you want to share your information about the rest-class-handler with ABAP it would be great if you share a use-case.. of course, there might be situations out there where it might be the right way, but that should not be a common blog.