ABAP Development, NW ABAP Gateway (OData)

Kotlin Application with SAP Gateway Part-1

Introduction

As a software developer, it is always good to step out of your area of expertise and learn a new language. This is especially good for ABAP developers, in order to stay fluent in Object-Oriented concepts, and to get a head start on where the language may be headed. For example, if you were familiar with Java when ABAP Objects was introduced, you would have been able to quickly adopt it, because ABAP Objects was modelled after Java. When the ABAP language was re-written in version 7.40+, familiarity with Java would have given you a great head start and enable you to quickly take advantage of the productivity gain. With the introduction of Fiori, familiarization with web development concepts would have also been very beneficial. Once familiar with Java, exploring other powerful languages, which are compatible with the Java Virtual Machine (JVM), will only make you a better ABAP developer. This is because languages like Groovy and Kotlin can teach you about higher level, advanced design concepts which are popular with today’s leading-edge web development community. Large software corporations, like SAP and Microsoft will keep an eye on these concepts which are rising quickly in popularity, and eventually adopt them into their products (i.e. HTML5 > Fiori, Java > C#, XML > OData). So, why not see the future, and keep your skills sharp!

Also Read: SAP ABAP 7.4 Certification Preparation Guide

Kotlin is rising very quickly in popularity and Google announced it was their preferred language for Android Development.

Interestingly, Kotlin is interoperable with both Java and JavaScript. Also, one goal of Kotlin is to be able to run anywhere and compile into many different native binaries.

This Blog is useful for ABAPers who want to get familiar with Kotlin, or Kotlin developers who want to understand SAP Gateway. Understanding the connectivity lessons learned in this Blog, should give you a jump start with your application. From there, add your own UI development and any ABAP code on the back end to accomplish any update in SAP (i.e. Sales Order Create BAPI call, etc.). This application is a simple console application to demonstrate all of the CRUD (Create, Read, Update, Delete) operations for a custom table in SAP. While I’m not sharing the code on GitHub, all of the code is in a single file (TableMaintenance.kt), so is easily used in your own project.

Application Overview

Here is an overview of how the application will work, representing the classical CRUD operations (Create, Read, Update, Delete) on a table:

Options 1-6 will be displayed with the following User Menu in a simple console application:

End User Walk through

Before diving into the code, let’s do a walk through of exactly what the simple console application will do.

Option 1 – Display All Data:

Enter option 1, and press enter, will display all data in the custom SAP Table ZTEST_KOTLIN.

After each option, the main menu is displayed again. Until you enter option 6 (Exit the Program), the main menu will continue to display.

Option 2 – Display a Record:

In order to display a single record, highlight and copy one of the Guid keys for a record, as below.

Option 3 – Create a Record:

Our intent is to maintain records for Customer Memos for a particular Order and Customer. To create a record, we’ll need to enter an Order Number, Customer Number and the Memo. A Guid key is auto-generated for us.

Option 4 – Update a Record:

To update a record, highlight and copy the Guid key first, then enter the new Customer Memo.

Until you hit option 6 to exit, you can continue to work…

Option 5 – Delete a Record:

Just like with an Update, copy the Guid key first, in order to delete a record. Let’s delete the above record we just created and updated.

Option 6 – Exit the Program:

Option 6 simply ends the program.

Now that we see how the program works, let’s write the code to accomplish all of the above…

Create an SAP Gateway Service

Create the Custom Table

First, we will create our custom table in SAP named ZTEST_KOTLIN. You can either perform the below steps, which will also allow you to create some test records using Excel.

First, let’s create a new String Data Element, which we will use for our Customer Memo field.

Enter the SAP Transaction SE11, and enter the Data type “ZZ_NOTE”, and click the “Create” button:

Select “Data Element” and continue:

Enter the following, then Save and Activate:

Activate

Execute the SAP Transaction SE11, and enter table name “ZTEST_KOTLIN”, then click on the “Create” button:

Enter the following fields for ZTEST_KOTLIN, and Save and Activate:

If you prefer Eclipse, we can create the table by entering the following DDL for our Table:

@EndUserText.label : 'Kotlin Tester'
@AbapCatalog.enhancementCategory : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #ALLOWED
define table ztest_kotlin {
  key mandt        : mandt not null;
  key guid         : /aif/exp_guid not null;
  date_updated     : sydatum;
  time_updated     : syuzeit;
  last_updated_by  : syuname;
  order_number     : vbeln;
  customer_number  : kunag;
  customer_message : zz_note;

}

Create a new SAP Gateway Project

Execute the SAP Transaction SEGW and click on the “Create Project” button:

Enter the following and continue:

We now have the following tree structure:

At this point, there are many ways to setup a basic CRUD Gateway Service. Among them is BOPF, which auto-generates code that allows you to easily maintain a Z Table via CDS View Annotations. Another method, is to setup a CDS View, which we expose as a service to quickly enable a “GET” or Read operation. As I recently witnessed at SAP Teched on newer versions of SAP, you can even right-click on your service, and auto-generate a Fiori App which displays your table. If your application evolves into something complicated, the road will lead to a more “custom” approach I will show in this Blog. It’s usually not long, before you need to start doing a “Deep Entity” POST, for example a Sales Order create with header and line item information, where the code generation method quickly reaches it’s limitation. Plus, if you are using Kotlin, let’s say to write a native Android Application, you may not be using Fiori at all. SAP is marketing a “Bring Your Own Language” (BYOL) approach with HANA. Yes, there are many plug-and-play options for a CRUD application, but the entire point of BYOL, is so organizations can utilize their existing pool of software engineers. For example, if you have a team of Kotlin developers, you may want to utilize them with your SAP installation. So, let’s proceed with a bare bones custom approach that gives us maximum flexibility, without the use of any code generation restrictions…

Let’s define our Entity, which represents the attributes of the ZTEST_KOTLIN table. Right-click on the “Data Model” node, and choose “Import > DDIC Structure”:

Let’s give our Entity an intuitive name, like “CustomerMemo”. Enter the following, and click “Next”:

Select all of the fields, except “MANDT”, and click “Next”:

Select the GUID field as the key, then click “Finish”:

Now if you expand out the Entity node, you can see your newly defined Properties, and the auto-generated Entity Set:

Save your new Data Model, and click on the “Generate Runtime Objects” button:

Accept the proposed defaults for our class names, and click Continue (Enter):

Click on the “Local Object” button on the next pop-up to complete (assuming you don’t want to transport it).

Now, navigate to the below node, to see the new Runtime Artifacts which were generated by the SAP Gateway Service Builder:

The MPC classes handle the data model definition and setup. The DPC classes handle the population of the entities with data. To keep it simple, you will always write code in the *DPC_EXT class. In the following sections, we will write code in the methods of our ZCL_ZKOTLIN_APP_DPC_EXT class to perform all of the CRUD operations.

Read Records

In order to setup our table Read operations, it would be nice to have some test data in the ZTEST_KOTLIN table. Because the Guid key field is auto-generated, that could be a little complicated. The easiest way, would be to use the ABAP code from this Blog, and enter some test data using Excel.

For this example, I’ve created the following 4 records displayed in Eclipse, below:

Alternatively, you can display the table records in the SAP transaction SE16. You will see the above 4 records used in the remainder of this Blog.

Read all Records

In order to read the complete table, and pass it back, we will implement the “GetEntitySet” Service. Navigate to the node “Service Implementation > GetEntitySet” and right-click and select “Go to ABAP Workbench”:

You’ll get a pop-up, which tells you that you still have to write some code in the method:

Hit Enter to continue.

This will take us to the ABAP Class Editor, where you can see lots of methods that were created by the SAP Gateway Service Builder:

In order to write our custom code, we need to do a Redefinition on the SAP generated methods. This is would be similar to a method Override in Java.

Page down to the bottom of the method list, and you will see the methods we will implement to support all of our CRUD operations:

To summarize, we will Redefine the following methods:

  • CUSTOMERMEMOSET_CREATE_ENTITY: Create a record, HTTP POST
  • CUSTOMERMEMOSET_DELETE_ENTITY: Delete a record, HTTP DELETE
  • CUSTOMERMEMOSET_GET_ENTITY: Read a single record, HTTP GET
  • CUSTOMERMEMOSET_GET_ENTITYSET: Read the entire table, and return all records
  • CUSTOMERMEMOSET_UPDATE_ENTITY: Update a record, HTTP PUT

Click on the Change button, to change the class:

Click on the CUSTOMERMEMOSET_GET_ENTITYSET method to place your cursor there, then click on the “Redefine Method” button on the upper-right:

This will open up the method as editable, where you will see some commented out template code:

Delete this code, and insert the following code:

 method CUSTOMERMEMOSET_GET_ENTITYSET.
    SELECT * FROM ztest_kotlin INTO TABLE et_entityset.
    SORT et_entityset BY date_updated DESCENDING time_updated DESCENDING.
  endmethod.

This simply selects all records in the table and returns them in the et_entityset internal table.

Save and Activate this code.

Read a Single Record

The above method will select all records. We’ll also need a method to select individual records. Go back to the method list, and place your cursor in the CUSTOMERMEMOSET_GET_ENTITY method, and click on the “Redefine Method” button, just as we did above:

Delete the commented code in the method:

Replace it with the following code:

method CUSTOMERMEMOSET_GET_ENTITY.
    DATA: ls_entity LIKE er_entity.

    io_tech_request_context->get_converted_keys( IMPORTING es_key_values = ls_entity ).

    SELECT SINGLE * FROM ztest_kotlin INTO er_entity
       WHERE guid  = ls_entity-guid.
  endmethod.

Save and Activate this code.

The above code will pull out the key passed from the application, and fetch a single record from the ZTEST_KOTLIN table.

Now that we have redefined a couple of methods, note the “Filter” checkbox in the upper-right:

Click on this checkbox, to filter out all of the other methods in the class, and show only those we’ve redefined thus far:

Testing the SAP Gateway

At this point, we have our first 2 methods for retrieving all records or a single record, so let’s pause for a moment and walk through how we can test them using the SAP Gateway Client. After all, we don’t want to toss this over the wall to our Kotlin developers, without first unit testing it.

Go back to the SAP Gateway Service Builder, and expand the node “Service Maintenance”:

We have a Gateway Hub defined as “GW_HUB”. If there is nothing under your “Service Maintenance” folder, this means that the SAP Gateway has not yet been setup for your SAP instance. You will need to set this up first. There are many good blogs out there that walk-through a setup.

Right-click on the Gateway defined for your system, in this case GW_HUB and select “Register”:

A typical test setup uses the “LOCAL” Alias, which we will use here:

In the center of the next screen, click the button “Local Object”, to avoid creating a transport:

Hit the Enter key, to accept all of the proposed defaults:

Back to our first screen, right click on the Gateway hub again, and select “SAP Gateway Client”:

Click “Yes” to be redirected to the system:

This brings us to our SAP Gateway Client, where we may test our new service:

Click on the “EntitySets” button:

This will bring up our Entity Set that we defined:

Double-click on it, to fetch the URI string for our Entity:

If you previously created test data in the ZTEST_KOTLIN table, you’ll get some data. Click on the “Execute” button:

I have 4 records in my table, and all records will be retrieved in OData XML Format on the right-hand pane:

Click on the button “Add URI Option”:

Double-click on “$format=json”:

This will append a JSON uri option to the end of our request:

Execute again, and our data is now in JSON Format (rather than standard default OData xml):

For our Kotlin application, because JSON is the most Java and Kotlin friendly format, we’ll be fetching our data in JSON format by appending this URI option.

Next, let’s test the GET for a single Record. Notice when we fetch all records, each record has it’s own “__metadata” attribute:

We can get the URI for that individual record, by copying that string, starting with “/sap/opu/”:

Paste the following string into the Request URI, to fetch a single record:

/sap/opu/odata/SAP/ZKOTLIN_APP_SRV/CustomerMemoSet(guid'0ed254e2-d1e6-1eda-809f-8d77d746d4dd')?$format=json

Execute, and the results will contain a single record:

One thing I wanted to point out, which you could get stuck on. Typically, if you are selecting a single record, and the key is a string, you can simply specify it. For example:

VendorGetSet/?$filter=(Matnr eq ‘10000030’)

If you tried to say (‘<your guide>’), you would get an error. If we go back to our Gateway Project, and double-click on “Properties” for our CustomerMemo Entity:

Properties:

Notice our key field Guid, is of type “Edm.Guid”:

The internal ABAP Type is TYPEKIND_HEX. When specifying this data type, you must place “guid” within the GET string – “CustomerMemoSet(guid’0ed254e2-d1e6-1eda-809f-8d77d746d4dd’)”.

One other feature of the SAP Gateway Client, is the ability to save our test cases. For example, if we’d like to save this GET test case, which retrieves this single record, we can go to the lower-right of the screen and click “Save Test Case”:

We can also setup Test Groups:

Now, we can retrieve this test case anytime, by clicking on the “Select” button:

Enter my Test Group:

Lists all tests in this test group:

Clicking on the “Test Case” link, will auto-populate the URI, with your previous test case:

You can now re-execute this test.

Testing a “GET” is pretty straightforward. Testing is a little trickier for create and update operations, so each section, below, includes testing instructions and how to include a payload with the HTTP Request. See the below section “Create Record” for the most detailed testing instructions on testing with a payload, and some recommended testing tools.

Create Record

To enable the HTTP POST method, right-click on the “Create” operation under the “Service Implementation” node and click “Go to ABAP Workbench”:

You’ll get a message that this operation has not yet been implemented, hit Enter to continue:

Ensure the “Filter” on the upper-right is unchecked, so we can find our CUSTOMERMEMOSET_CREATE_ENTITY method:

Switch to Change Mode to make the class editable.

Click on this method, to place your cursor into the row for method CUSTOMERMEMOSET_CREATE_ENTITY:

Next, click on the “Redefine Method” button:

This brings you into the code for this method:

Replace the above commented code with the following:

METHOD customermemoset_create_entity.
    DATA: lw_record TYPE zcl_zkotlin_app_mpc=>ts_customermemo.

    io_data_provider->read_entry_data( IMPORTING es_data = lw_record ).
    IF lw_record-order_number     IS INITIAL OR
       lw_record-customer_number  IS INITIAL OR
       lw_record-customer_message IS INITIAL.
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception.
    ENDIF.

    "Create a record in the database...
    CLEAR: lw_record-date_updated, lw_record-time_updated, lw_record-last_updated_by,
           lw_record-guid.
    lw_record-date_updated    = sy-datum.
    lw_record-time_updated    = sy-uzeit.
    lw_record-last_updated_by = sy-uname.
    "Generate a unique key (guid)...
    TRY.
        lw_record-guid = cl_system_uuid=>if_system_uuid_static~create_uuid_x16( ).
      CATCH cx_uuid_error INTO DATA(lo_guid_error).
        RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception.
    ENDTRY.

    INSERT ztest_kotlin FROM lw_record.
    COMMIT WORK AND WAIT.
    IF sy-subrc = 0.
      "New record was created successfully...
      er_entity = lw_record.
    ELSE.
      "Entity not found
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
        EXPORTING
          textid      = /iwbep/cx_mgw_busi_exception=>resource_not_found
          entity_type = iv_entity_name.
    ENDIF.
  ENDMETHOD.  

Save and Activate the above code.

The above code does the following:

Fetch the incoming record from the Gateway:

io_data_provider->read_entry_data( IMPORTING es_data = lw_record ).

For a creation, the fields we need from the user are order number, customer number and customer message (i.e. Memo). Aside from that, we will auto-populate all other fields:

  • date_updated = Date the user created or last updated the record.
  • time_updated = Time the user created or last updated the record.
  • last_updated_by = The SAP user name of the user who last created or updated the record.

SAP provides a class to auto-generate a unique GUID, which will represent the new key for our new record:

"Generate a unique key (guid)...
    TRY.
        lw_record-guid = cl_system_uuid=>if_system_uuid_static~create_uuid_x16( ).
      CATCH cx_uuid_error INTO DATA(lo_guid_error).
        RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception.
    ENDTRY.

Finally, we do the insert and commit into the database.

Now, to test takes a bit of effort. You can easily waste a couple of days figuring this one out, so I hope the following steps will save you some time!

When testing with the SAP Gateway Client, some authorization items are handled for you, so keep this in mind. Let’s first test with the SAP Gateway Client, to start with the easiest approach.

Go back to our project, and right click on your Gateway hub, then “SAP Gateway Client”:

There is a feature, whereas you can perform an HTTP GET, then turn this data into an update method (i.e. POST, PUT, DELETE, etc.). This is the easiest way to get the properly formatted data, etc. Let’s use our URI from earlier, to get a single record. Enter the following into the Request URI or click “Select” and retrieve the earlier test case:

/sap/opu/odata/SAP/ZKOTLIN_APP_SRV/CustomerMemoSet(guid'0ed254e2-d1e6-1eda-809f-8d77d746d4dd')?$format=json

Now, execute the above:

On the top of the HTTP Response section, click on the “Use as Request” button:

This moves the data into the left-hand pane for an HTTP Request:

Next, remove the JSON URI Option and the GUID at the end of the string. You now have the following URI:

/sap/opu/odata/SAP/ZKOTLIN_APP_SRV/CustomerMemoSet

In looking at our custom code in the method, we recall that the required fields are Order Number, Customer Number and Customer Message (Memo). Let’s overwrite those fields in the HTTP Request, with our new data:

Even though we are doing a “Create”, you still need to specify a GUID and all fields in the payload request. The GUID could be all zeros, but must be in the same format. Since our method will generate a GUID and ignore the one that is passed in, we’ll just leave ours as-is in the request.

Next, change the HTTP Method to “POST”, instead of “GET”:

Now execute and you should see the following, with a success code 201, plus your newly generated data in the response:

Notice our new record has a new GUID of “0ed254e2-d1e6-1eea-8dfa-d2e289485cae”:

Notice when you execute the POST, a X-CSRF-Token appears in the upper left “HTTP Request” section:

The SAP Gateway handles some steps for us, but when we call the service from an external application or testing tool, we’ll need to handle this ourselves. More on this later.

At this point, you may want to save this as a test case for later use, by clicking on the “Save Test Case” button in the lower right corner.

To prove that this worked, copy your newly generated GUID, and do a GET in the test tool, with the URI:

/sap/opu/odata/SAP/ZKOTLIN_APP_SRV/CustomerMemoSet(guid'0ed254e2-d1e6-1eea-8dfa-d2e289485cae')?$format=json

Switch the HTTP Method back to “GET” and execute:

This will fetch our new record:

Because we will be building a Kotlin application which will be calling the Gateway Service externally, now is a good time to test with another tool, unrelated to the SAP Gateway Client.

Let’s walkthrough a test with the Advanced Rest Client (ARC). There are 3 important items that the SAP Gateway handles for us, which we must do ourselves if calling the service from an external application:

  1. Authorization – This is the same as your SAP Login ID and password. Since we are already logged into SAP when we use the SAP Gateway Client, nothing was needed.
  2. X-CSRF-Token – Cross-Site Request Forgery to prevent malicious attacks on your website or service.
  3. Set Cookie – The SAP Gateway can also generate a cookie, which you can use to call-back the service. This assures the SAP Gateway, that the request is coming from the same browser or application. Another level of security that you get, along with the X-CSRF-Token.

Only a login (Authorization) is required for a GET operation, because it is Read only. Because the other activities (Create, Update and Delete, a.k.a. “CUD”) are performing changes in your backend system, more robust authentication is required. If you search on the community websites for the above, you’ll see lots of confusion, and people trying to disable it. Don’t disable it, just play by the rules and figure it out. Hopefully this section will save you some time and hardship. Here is an overview of what we will need to do:

Here is the detailed information, for each process step, above, when using the “Advanced REST Client” software:

Fetch Authorization Data

First, we need to obtain an encrypted Basic Authorization string, which will contain our SAP Logon ID and Password. This allows us to auto-login to the SAP Gateway programmatically. In addition to the below instructions, I’ve also included instructions on obtaining the Authorization string using IntelliJ IDE in the Reference section at the end of this blog.

Open the ARC (Advanced REST Client) testing tool. Enter the same URL, which we were testing for our GET earlier:

http://<your server name>/sap/opu/odata/SAP/ZKOTLIN_APP_SRV/CustomerMemoSet

In your ARC tool, select the menu path “File > New tab”:

Choose the Method “GET” and enter the url:

Click on the “Authorization” Tab and choose “Basic authentication”:

Enter your SAP ID and password:

Click on the “HEADERS” tab, and you will see how this encrypted string will be passed in the header of the HTTP request:

Click “ADD HEADER” to add another header, and enter the following:

Name: X-CSRF-Token

Value: Fetch

Now, click on the “SEND” button to perform the HTTP GET. Expand out the “DETAILS” on the right-hand side:

Note the RESPONSE HEADERS will contain the Cookie and Token:

Copy the string from the second “set-cookie”:

SAP_SESSIONID_S4R_100=4Ctq0h<blah, blah, blah>lRU4rxHqilwO0lTi0eY%3d; path=/

Copy the string for the “x-csrf-token”:

ehAczq<blah, blah, blah>Zv0-g==

These are the 3 bits of information we need, to perform the database update operations (Create, Update or Delete), below:

  1. Basic Auth String
  2. Cookie String
  3. CSRF Token String

Copy the 3 above strings, then proceed below…

Database Change (CUD Operation)

Using our 3 HTTP header strings we obtained with the GET (Fetch), above, lets perform the same steps we did with the SAP Gateway Client to do a Create (HTTP POST) operation.

Note! The token and cookie can expire on the server, so if it’s been a while since you did the above GET, then run it again and get a new token and cookie, before proceeding.

Add a new Tab (Request Editor) in the ARC:

Copy our 3 strings, from the above GET and add them as new Headers. Also, add the below additional “Content-Type” and “Accept” strings. Here is the complete HTTP Header set:

The strings above are:

X-CSRF-Token: <your token from the above GET result>

Authorization: <your Basic auth string, used in the above GET section>

cookie: <your cookie from the above GET result>

Content-Type: application/json

Accept: application/json

Now, switch the Method to “POST” and enter the following URL, same as the one earlier when testing on the SAP Gateway Client:

Now, go to the “Body” tab, and enter the following JSON:

{
  "d": {
    "Guid": "00000000-0000-0000-0000-000000000000",
    "OrderNumber": "8888",
    "CustomerNumber": "9999",
    "CustomerMessage": "This is a new Memo from the Advanced REST Client!"
  }
}

Since the Guid will be ignored, we could place all zeros in it, but be sure to follow the exact same format, including the dashes (-) and the same length.

Press the “SEND” button to execute the HTTP POST to create our new record:

If all goes well, you should see the following success result, including the newly created record:

To see the above record, you can copy the newly created Guid Key, from the above results, and do another GET from either the SAP Gateway Client or ARC. Here is a complete table listing, from Eclipse, with our new record:

At this point, we’ve tested first with the SAP Gateway Client, to prove our GET and POST methods worked correctly. Next, we used a REST tool, called “Advanced REST Client” (ARC) to ensure our methods worked when calling from an external application, with necessary authorization tokens. We can now confidently tell our Kotlin developers that our SAP Gateway service is ready to be called and has been unit tested. Before giving them the green light, let’s complete the Update and Delete operations.

Update Record

Go back to the SAP Gateway Service Builder (Transaction SEGW), and go to the following node and right-click on the “Update” method, then “Go to ABAP Workbench”:

You’ll get the warning that it’s not yet implemented:

Enter to continue.

Uncheck the “Filter” checkbox, if it’s on:

Go into Change Mode for the Class:

Single click into the row for the method CUSTOMERMEMOSET_UPDATE_ENTITY:

Click on the “Redefine Method” button:

Overwrite the commented code in the method, with the following code:

method CUSTOMERMEMOSET_UPDATE_ENTITY.
    DATA: lw_record TYPE zcl_zkotlin_app_mpc=>ts_customermemo.

    io_data_provider->read_entry_data( IMPORTING es_data = lw_record ).

    "The key is "guid"...
    READ TABLE it_key_tab INTO DATA(lw_key) INDEX 1.

    "Make sure the value matches the one in the OData payload...
    IF lw_key-value = lw_record-guid.
      "Update the record in the database...
      CLEAR: lw_record-date_updated, lw_record-time_updated, lw_record-last_updated_by.
      lw_record-date_updated    = sy-datum.
      lw_record-time_updated    = sy-uzeit.
      lw_record-last_updated_by = sy-uname.
      UPDATE ztest_kotlin FROM lw_record.
      COMMIT WORK AND WAIT.
      IF sy-subrc = 0.
        "Entity was found and updated...
        er_entity = lw_record.
      ELSE.
        "Entity not found
        RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
          EXPORTING
            textid      = /iwbep/cx_mgw_busi_exception=>resource_not_found
            entity_type = |{ iv_entity_name } ('{ lw_key-value }')|.
      ENDIF.
    ENDIF.
  endmethod.

Save and Activate your code.

For testing, we will repeat the same steps as shown in the above “Create Record” section, except we will do an HTTP PUT, instead of an HTTP POST. Plus, we’ll have to pass the complete record in the HTTP payload, along with the Guid key for the record we want to update. The testing steps in this section are more summarized. For a very detailed explanation of the steps to test an HTTP operation with a database update, see the “Create Record” section, above.

Go to the SAP Gateway Client:

Retrieve the Guid key, for any existing record you want to update.

Enter the request URI:

/sap/opu/odata/SAP/ZKOTLIN_APP_SRV/CustomerMemoSet(Guid=guid'0ed254e2-d1e6-1eda-8fb0-2a4781e3b5c5')

Select the PUT method:

Enter your JSON in the HTTP Request payload section:

{
  "d" : {
    "Guid" : "0ed254e2-d1e6-1eda-8fb0-2a4781e3b5c5",
    "DateUpdated" : "\/Date(1578528000000)\/",
    "TimeUpdated" : "PT13H10M38S",
    "LastUpdatedBy" : "JCAPPS",
    "OrderNumber" : "8888",
    "CustomerNumber" : "9999",
    "CustomerMessage" : "This is my updated Memo!"
  }
}

Execute, and you will get the following results:

Confirm that the record update was successful:

To perform this test with the Advanced REST Client (ARC), perform the same steps in the “Database Change (CUD Operation)” section, above, but include the above payload, and your Guid Key in the url. As with the Create Operation, perform a GET first, to fetch your authorization token data. Then, do an HTTP PUT Method:

Click the “SEND” button to execute the above record update.

Delete Record

Go back to the SAP Gateway Service Builder (Transaction SEGW), and go to the following node and right-click on the “Delete” method, then “Go to ABAP Workbench”:

You’ll get the warning that it’s not yet implemented:

Enter to continue.

Uncheck the “Filter” checkbox, if it’s on:

Go into Change Mode for the Class:

Single click into the row for the method CUSTOMERMEMOSET_DELETE_ENTITY:

Click on the “Redefine Method” button:

Overwrite the commented code in the method, with the following code:

METHOD customermemoset_delete_entity.
    DATA(lt_keys) = io_tech_request_context->get_keys( ).

    READ TABLE lt_keys WITH KEY name = 'GUID' INTO DATA(ls_key).
    DATA(lv_guid) = ls_key-value.

    "Ensure the GUID is valid...
    SELECT SINGLE mandt INTO @DATA(l_mandt) FROM ztest_kotlin
      WHERE guid = @lv_guid.
    IF sy-subrc <> 0.
      "Record not found...
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
        EXPORTING
          textid      = /iwbep/cx_mgw_busi_exception=>resource_not_found
          entity_type = |{ iv_entity_name } (Guid='{ lv_guid }')|.
    ENDIF.
    "Delete the record from the database...
    DELETE FROM ztest_kotlin WHERE guid = lv_guid.
    COMMIT WORK AND WAIT.
    IF sy-subrc <> 0.
      "Delete Failed...
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
        EXPORTING
          textid      = /iwbep/cx_mgw_busi_exception=>resource_not_found
          entity_type = |{ iv_entity_name } (Guid='{ lv_guid }')|.
    ENDIF.
  ENDMETHOD. 

Save and Activate your code.

For testing, we will repeat the same steps as shown in the above “Create Record” section, except we will do an HTTP DELETE, instead of an HTTP POST. Because we are simply deleting the record, we only need to provide the Guid key in the URL and no payload is needed. The testing steps in this section are more summarized. For a very detailed explanation of the steps to test an HTTP operation with a database update, see the “Create Record” section, above.

Go to the SAP Gateway Client:

Retrieve the Guid key, for any existing record you want to delete.

Enter the request URI:

/sap/opu/odata/SAP/ZKOTLIN_APP_SRV/CustomerMemoSet(Guid=guid'0ed254e2-d1e6-1eda-8fb0-2a4781e3b5c5')

Select the DELETE method:

Execute, and you will get the following results:

Confirm that the record was successfully deleted:

To perform this test with the Advanced REST Client (ARC), perform the same steps in the “Database Change (CUD Operation)” section, above, with no payload, and your Guid Key in the url. As with the Create Operation, perform a GET first, to fetch your authorization token data. Then, do an HTTP PUT Method:

Click the “SEND” button to execute the deletion of the record.

Also Read: SAP ABAP 7.5 Certification Preparation Guide

Leave a Reply

Your email address will not be published. Required fields are marked *