Introduction to OData and how to implement them in ABAP (2024)

Some years ago I created a small introduction into OData development for my colleagues at newFounders. Last week some developers at my current client told me this was still a nice document if you want to start with OData development, so I decided to share it with the community. I hope you enjoy it and learn something from it. I still have hopes to create a follow-up with covering the topics expanded and deep entitysets, batches and function imports, but only time will tell if this will happen.

Introduction

OData is the current default way to communicate with an SAP backend, be it for an (SAPUI5) frontend or any other integration scenario. The goal of this document is to get an ABAP developer up and running with understanding and implementing OData services in an SAP ABAP-based backend system.

ODataservices;background information and how to test them.

I’lltry to explain what OData is by using calls on existing OData services, and expanding those calls with more options.I’llstart using a tool calledPostmansowe’llneed to get this tool as the first step.

Warning: I use standard BP functionality, so only use this tutorial in a test-environment.

Postman

Install Postman (https://www.getpostman.com/downloads/).Postmanis a tool to test & execute HTTP(S) REST calls. As an alternative you can use Curl (http://curl.haxx.se/), but I will use Postman in thistutorial.

SAP ABAP backend.

We will use some demo-services and demo-data from SAP. If you find that the underlying tables are empty, you can fill them usingtransactionSEPM_DG.I assume you know the hostname and port number of your SAP installation. If not, try to find it in transaction SMICM –>Go To–> Services.

Testing your environment.

Start Postman, create a Collection to store your tests & calls in, and create your first OData call to test the connection to your backend.We’lluse a standard SAP OData service:http://YourSystemURL:Portnumber/sap/opu/odata/IWBEP/GWDEMO/?$format=xml.In Postman this looks like:

Introduction to OData and how to implement them in ABAP (1)

If you try this call now,you’llget a logon error.

Introduction to OData and how to implement them in ABAP (2)

We have to add our credentials in the tab Authorization (type:Basic Auth):

Introduction to OData and how to implement them in ABAP (3)

And ifall’scorrect,you’llsee the entity-types in the returned body afterpressing <SEND>you’llget results:
Introduction to OData and how to implement them in ABAP (4)

Question:
What would you have to doin order toget your response in a JSON format?

OData background

The format of an OData URL is shown below.
Introduction to OData and how to implement them in ABAP (5)

This URL points to a Service Document, which for OData, exposes two key things:
The entity sets, functions and singletons that can be retrieved.
–A metadata document (which shows the packaging format of the data)

To view the entity sets, open the link in a new browser tab. As you scroll through the page, you will seeall the entity sets (or collections) listed.
http://YourSystemURL:Portnumber/sap/opu/odata/IWBEP/GWDEMO/?$format=json

The metadata document will show the individual fields,formatsand navigation properties of all the collections. To view the metadata for any OData service, append $metadata at the end of the URL inyour browser.
http://YourSystemURL:Portnumber/sap/opu/odata/IWBEP/GWDEMO/$metadata

To see the data that is served by the OData service, just enter the collectionyou’dlike to see:
http://YourSystemURL:Portnumber/sap/opu/odata/IWBEP/GWDEMO/SalesOrderCollection?$format=json

If you try this URI,you’llsee that it takes a long time to get all the results. Most of the time you just want to display a few of the items out of the collection.In order toget only a fewitemsyou can enhance the URI with some options like$top,$skiptoken, $orderby, $filter:
http://YourSystemURL:Portnumber/sap/opu/odata/IWBEP/GWDEMO/SalesOrderCollection?&$top=10&$skiptoken=5&$filter=BillingStatus%20ne%20’P’&$format=json

In the above URI we want 10 Sales Orders that are not paid, skipping the first 5 entries. Note the “%20”; this is an encoded form for a space(“ ”). For more information:https://www.w3schools.com/tags/ref_urlencode.asp

Stillwe get a lot of data; we can choose to only return a subset fields by using theoption$select.
http://YourSystemURL:Portnumber/sap/opu/odata/IWBEP/GWDEMO/SalesOrderCollection?&$top=10&$skiptoken=5&$filter=BillingStatus%20ne%20’P’&$select=SalesOrderID,Status,NetSum,Currency,CustomerName&$format=json

But wouldn’t it be nice to get the ordered products in the line items as well? For that we have theoption$expand:
http://services.odata.org/V2/Northwind/Northwind.svc/Products?$format=json&$top=10&$select=ProductName,UnitPrice,Supplier&$expand=Supplier
(Unfortunately, the SAPGWDemoOData servicedoesn’tsupport the$expandvery well, so this is a different example)

Luckily, there is anotheroptionto go from one Sales Order to the line items. That is to define the Sales Order with its key (like this:http://YourSystemURL:Portnumber/sap/opu/odata/IWBEP/GWDEMO/SalesOrderCollection(‘1244D0D392BB1EE5B49987627D705A45’)) and use the other way to expand to the line items by using a path in the URI:
http://YourSystemURL:Portnumber/sap/opu/odata/IWBEP/GWDEMO/SalesOrderCollection(‘1244D0D392BB1EE5B49987627D705A45’)/salesorderlineitems

Please note that GUID’s are used in these last two URI’s. You will not have the same GUID’s in your system, so you should change your URI’s in order to get results.

Question:
What could be the use of combining $top, $skip and $count ?
Hint: Have a look athttps://blogs.sap.com/2013/03/20/using-odatas-top-skip-and-count/ andhttps://blogs.sap.com/2017/12/06/display-countfilterorderbyinlinecounttop-and-skip-operations-using-odata-services/

Could you make an URI where you retrieve information on a sales order and its line-items, selecting only a few fields? Do you need to include the key in theselectionto get the line-items? Why would you usea selectionon fields?

So far, we just retrieved information. Now we want to make some changes. You can use the standard HTTP operations GET, POST, PUT, PATCH, MERGE & DELETE.We’llchange the something simple, theProductDescriptionof a Product. Get a list of some products:
http://YourSystemURL:Portnumber/sap/opu/odata/IWBEP/GWDEMO/ProductCollection?$top=20

Select a Product you want to change and get the details. The URI for the identification is given, for instance
http://YourSystemURL:Portnumber/sap/opu/odata/IWBEP/GWDEMO/ProductCollection(‘1244D0D392BB1EE5B49984552646FA45’)
Usethe body of the result as input for the update
.

Now search for the tag <ProductDescription> andchange the description. Make sure you enter the body as XML, and set this in Postman as XML as well:

Introduction to OData and how to implement them in ABAP (6)Introduction to OData and how to implement them in ABAP (7)

Choose the PATCH operation and press SEND.

Introduction to OData and how to implement them in ABAP (8)

If all went well, you have changed the description of this product. Check with a GET operation.

If you get an error referring to anx-csrf-token, change the GET request by adding the following in the header:x-csrf-token=fetch. In the responseyou’llget a token back, use this value in the PATCH operation:
Introduction to OData and how to implement them in ABAP (9)

CSRF (Cross-site Request forgery) is the name of a way of session piggy-back riding that can be used for malicious means.In order toprevent this, a CSRF token issubmittedby the SAP system so the browser can use this token insubsequentcalls in a secure way. See for more informationhttps://en.m.wikipedia.org/wiki/Cross-site_request_forgeryandhttps://stackoverflow.com/questions/5207160/what-is-a-csrf-token-what-is-its-importance-and-how-does-it-work.

Question:
What would the difference be between the PUT and PATCH operations?
What is the result status of the PATCH call? Why?
What should you put in the body of a DELETE operation?

For more information and exercises about OData please visit:
https://developers.sap.com/tutorials/hcp-webide-odata-primer.html
https://blogs.sap.com/2013/10/03/lets-talk-odata-shall-we/
https://sapyard.com/odata-and-sap-netweaver-gateway-part-i-introduction/
https://blogs.sap.com/2016/02/08/odata-everything-that-you-need-to-know-part-1/ and thesubsequentblogposts in this series.
https://www.odata.org/getting-started/basic-tutorial/

Anda very good reference concerning OData: https://www.odata.org/documentation/odata-version-2-0/uri-conventions/

Creating a simple OData service in SAP.

Introduction.

As our focus will be on creating an OData service in SAP,we’ll use a quite straightforward data model: The Business Partner and use for its sub nodes address, telephone numbers etc. We’lluse the standard BAPI’s and function modules, so wedon’thave to do too much ABAP.

Most implementations of OData services in the SAP world use a separate Gateway system for serving OData and a separate system where the dataactually resides(oftentimes an ECC-system).

Question: What would be the advantage to have two different systems: one for storing the data, the other for serving the OData, instead of having only one system serving both purposes?

Defining the OData service.

In transaction‘SEGW’ you can define your OData service.Let’sstart by creating a read service (HTTP “GET” operation) for the Business Partner entity. Click on create and fill in the requested parameters.An empty OData project appears.

Introduction to OData and how to implement them in ABAP (10)Introduction to OData and how to implement them in ABAP (11)

What do we see in the tree?
First, the name of the OData service. In this case “Z_JW_BUSPARTNER”.
Underneath we find the “Data Model” node. In the sub nodes of the “Data Model” node the data definition and the relations between them will be defined. Any functions will be seen here as well.
The next node is the “Service Implementation”.In here the possible operations are defined for the entities in the “Data Model”.
In the “Runtime Artefacts” the (generated) classes will be summed.
In the “Service Maintenance” the details of the registration of service on the Gateway-system is displayed.

To define the fields for the business partnerwe’llimport the BUT000 structure, but only use some fields. Right-click on the “Data Model”node and select “Import –>DDIC structure”.

Introduction to OData and how to implement them in ABAP (12)Introduction to OData and how to implement them in ABAP (13)

Fill in the fields and select the ones you want to use. As I will use my service only for organizations, I will initially only use the fields “Partner”, “NAME_ORG1”, “NAME_ORG”, “BU_SORT1” & “BU_SORT2”. The field “Partner” will be marked as key.

Introduction to OData and how to implement them in ABAP (14)Introduction to OData and how to implement them in ABAP (15)

Question: Why do we need to mark at least one entry as key?

Now we have tospecify what we can do with the fields. As we want to be able to have all fields available for CRUD, we mark them all for these operations. Note however, that we do not mark all fields.

Introduction to OData and how to implement them in ABAP (16)

Question: which fields are not marked and why?

After generating the first part of the OData service is created!Best practice is to leave the suggested names as they are, but you can change the names of the classes.Later on,we’lluse the classes with the “_DPC_EXT” and “_MPC_EXT” for implementing our own logic.

Introduction to OData and how to implement them in ABAP (17)

After generating you should register the service in SICF. Select the entry under the node “Service Maintenance”.Just press the button “Register.

Introduction to OData and how to implement them in ABAP (18)Introduction to OData and how to implement them in ABAP (19)

And we cantest itimmediately!

Testing OData services in the SAP Gui.

Testing the OData service is quite easy. SAP created a separate transaction for testing OData services, that you can reach by pressing the button with the monkeywrench:

Introduction to OData and how to implement them in ABAP (20)

You’ll reach the following screen. The basic URI should be pre-filled.

Introduction to OData and how to implement them in ABAP (21)

By using the buttons “Entity Sets” and/or “Add URI Option” you can manipulate the URI.

Question:
Try to get the metadata for your service, as well as the entries for the business partners.

What is the return status of the call for the entries retrieving the business partners?

Please note that only the last part of the URI is displayed in this SAP transaction, starting at the service root.

Implementing code for the OData service to get a list of entities.

You will have noticed that the service gives no results yet, but a “501” error (not implemented). And that is exactly what we are about to do. While generating the service, the system asked for names for classes. We will use the Data Provider class defined there. Standard it is the class ending with “_DPC_EXT”,you can find the name for the class under the“Service Implementation”node as well. There are five inherited methods that are related to the Business Partner entity.

Introduction to OData and how to implement them in ABAP (22)

The first operation to be published are the read-operation, andthereforthe methods “BUSINESSPARTNERS_GET_ENTITY” and “BUSINESSPARTNERS_GET_ENTITYSET” will be re-implemented.

Question: What is the difference between those two methods?

As we used the data dictionary element “BUT000” as the source for our entity, we can directly select entries from that table into the entity. In most cases you will use a field list and a join in yourselectionor use a BAPI or function call.

Warning: This solution might lead to performance problems in systems with many business partners.

Implementation for theentity set:

METHOD businesspartners_get_entityset. "Redefinition SELECT * FROM but000 INTO TABLE et_entityset. ENDMETHOD. 

With this single line of code, you have your OData running for retrieving all business partners!

Now have a better look at the method you just re-implemented. As you see, there are many parameters in this method. Have a look at them in the debugger (set an externalbreakpoint); quite a few speak for themselves. The most important is the exporting parameter “ET_ENTITYSET”.In this parameter you will return your results, which will eventually be the result set of the OData service.
The IS_PAGING parametercontainsthe $top & $skip options, theIT_FILTER_SELECT_OPTIONS; IT_KEY_TAB; IT_NAVIGATION_PATH IT_ORDER, IV_FILTER_STRING and IV_SEARCH_STRING parameters are for other options in the OData URI. A few of them are implemented by standardclasses in SAP. See for more information this blog:https://blogs.sap.com/2017/12/06/display-countfilterorderbyinlinecounttop-and-skip-operations-using-odata-services/.

Implementing these standard functionalities will lead to the following method:

METHOD businesspartners_get_entityset. "Redefinition SELECT * FROM but000 INTO TABLE et_entityset. *** $inlinecount query option for all count entries. IF io_tech_request_context->has_inlinecount( ) = abap_true. DESCRIBE TABLE et_entityset LINES es_response_context-inlinecount. ELSE. CLEAR es_response_context-inlinecount. ENDIF. *** The module for Filter conditions CALL METHOD /iwbep/cl_mgw_data_util=>filtering EXPORTING it_select_options = it_filter_select_options CHANGING ct_data = et_entityset. *** The module for $top and $skip Query Options CALL METHOD /iwbep/cl_mgw_data_util=>paging EXPORTING is_paging = is_paging CHANGING ct_data = et_entityset. *** The module for Orderby condition CALL METHOD /iwbep/cl_mgw_data_util=>orderby EXPORTING it_order = it_order CHANGING ct_data = et_entityset. ENDMETHOD. 

Wouldn’t it be nice if we offered a message if wecouldn’tfind any results?So,let usimplement that.In the methods for returning entities two exceptions are defined: one of type “/IWBEP/CX_MGW_BUSI_EXCEPTION” and one of type “/IWBEP/CX_MGW_TECH_EXCEPTION”.The first one is for problems with entities, like authorizations or no valid entries found, the second one is for technical problems, like unexpected input,operatorsor things like that. Such a message was displayed after the service was just generated, but not methods were implemented yet. This exception leads to an HTTP-error message(e.g.A 501-result).

Furthermore, we can make use of a message container to store multiple messages. Seehttps://help.sap.com/doc/saphelp_gateway20sp12/2.0/en-US/25/21aecce9db435daaea433071ff7d94/content.htm.

The implementation of this service is completed by adding a check on theselectionto see if anything was found:

 IF sy-subrc NE 0. "No BP's found. DATA(lo_message_container) = me->mo_context->get_message_container( ). lo_message_container->add_message( iv_msg_type = /iwbep/cl_cos_logger=>warning iv_msg_id = 'SA' "SA(419) = No objects found iv_msg_number = 419 iv_add_to_response_header = abap_true ). ENDIF. 

The message container is more versatile than just this method. Just explore and try things out.

Feel free to test this service.

Implementing the Read-service for a single entity.

With the experience of implementing the service for getting an array of results for theresult set, it is easy to implement the service for getting one entry. The method to be redefined here is the one called “BUSINESSPARTNERS_GET_ENTITY”.
The service expects a valid key for the entity, in this case the key is a business partner number. This istransported to the method in parameterIT_KEY_TAB.A simple solution could be the following coding:

DATA(lv_bu_partner_raw) = CONV bu_partner( |{ it_key_tab[ name = 'Partner' ]-value }| ). DATA(lv_bu_partner) = CONV bu_partner( |{ lv_bu_partner_raw ALPHA = IN }| ). SELECT SINGLE * FROM but000 INTO CORRESPONDING FIELDS OF er_entity WHERE partner = lv_bu_partner. 

Question: which fault-handling would you implement? How will you get the messages to the caller of the OData service?

Implementing the Update / Create /Deleteservice.

Getting information is one thing, but we would like to really do things with our entities.I’llexplain the Update service and leave it up you to implement the create anddeleteservices as a practice.You’llbe able to guess which methods to redefine by now.

The data which should be updated in the system is transferred via the parameterio_data_provider. You can retrieve the data by calling methodread_entry_data( ). The update will take place using the HTTP “put” method. The keyofthe input is also given in theIT_KEY_TAB parameter, it is good practice to compare thevalue from theio_data_providerwith the value in theIT_KEY_TABparameter.

It is also nice to give the updated value back to the user, via parameter ER_ENTITY.

The simplified coding could look like this:

 io_data_provider->read_entry_data( IMPORTING es_data = ls_entity ). READ TABLE it_key_tab INTO DATA(ls_key_tab) INDEX 1. * make sure the value matches with the OData payload IF ls_key_tab-value EQ ls_entity-partner. CALL FUNCTION 'BAPI_BUPA_CENTRAL_CHANGE' EXPORTING businesspartner = ls_entity-partner TABLES return = lt_return. ELSE. * raise message: entity not found ENDIF. er_entity = ls_entity. 

Tip for easy testing:You’dlike to update an existing entity; so first execute a GET for a single entity. Copy the response-result and use that as the starting point for your HTTP Request body. In the SAPGUI there is even a nice button for it:Anddon’t forget to either add leading zeroes in your coding if you want to beforgiving, orput the correct key with leading zeroes once you call an update.

Question: What status code will you receive onceyou’vemade a successful update? Why would we get thisparticular statuscode?

Now continue with implementing the create and deleteservices and test them. For creating BusinessPartnersyou could use “BAPI_BUPA_CREATE_FROM_DATA“. Use category ‘1’ for persons and ‘2’ for organizations.

Fordeletingyou can either just set the archiving marker, of you could re-use the coding of the SAP reportsBUPA_PREPARE_DA (transaction BUPA_PRE_DA) and BUPA_TEST_DELETE (transaction BUPA_DEL).

Question: Is it necessary to provide a body with details for the HTTP-request for thedeleteoperation?

Question: How will you know what the key is of the entity that was created with a HTTP-POST operation.

Adding associations to your OData service

Now we have our simple OData service running, it is time to enhance our service.We’lladd the possibility to add addresses.For the sake of simplicity,I’llonlymaintaintelephone numbers in this example. For the implementationI’veused the function modules: BAPI_BUPA_ADDRESSES_GET, BAPI_BUPA_ADDRESS_GETDETAIL,BAPI_BUPA_ADDRESS_ADD, BAPI_BUPA_ADDRESS_CHANGE and BAPI_BUPA_ADDRESS_REMOVE.

In the OData service a second entity is created for the telephone numbers (Telephone &TelephoneSet). In this example only theminimumfields aremaintained:

Introduction to OData and how to implement them in ABAP (23)

Now it is time to add the association between partner and telephones.

Open the Data Model node of the OData service and select createon Associationsnode.

Introduction to OData and how to implement them in ABAP (24)

The association is from the Business Partner to the Telephone, and hence we name itBusinessPartnerGetTelephones. Any business partner can have zero to many telephone numbers, and that is used in the cardinality. If needed, generate the navigation properties as well. Navigation Property: A property of an Entry thatrepresentsa Link from the Entry to one or more related Entries. A Navigation Property is not a structural part of the Entry it belongs to.

Introduction to OData and how to implement them in ABAP (25)

Enter the “referential constraints” (the fields used for linking the two entities).

Introduction to OData and how to implement them in ABAP (26)

And accept the overview:

Introduction to OData and how to implement them in ABAP (27)

And the Association is created, including the Navigation Properties.

Introduction to OData and how to implement them in ABAP (28)

Question: How would the URI look like to test the Association?

What is the difference between an URI with $expand and using an URI with an Association/Navigation path? (Hint see thisarticle)

What would the result be if you tested the URI in theprevioustwo questions? Why?

After defining theservices,the implementation stillmustbe coded. Once this is completed, test your solution by creating a business partner, adding,changing,anddeletingtelephone numbers. It would be nice to test the navigation using both a Navigation Property and an $expandoption.
For instance:/BUSPARTNER_SRV/BusinessPartnerSet(’14’)/TelephoneSet and/BUSPARTNER_SRV/BusinessPartnerSet(’14’)/?$expand=TelephoneSet.

Conclusion

You have just created a basic OData service, and learned something about the theory behind OData. I hope you enjoyed it.

Introduction to OData and how to implement them in ABAP (2024)

FAQs

How to create OData step by step? ›

In SAP, we use SEGW transaction code to create an OData Service. I tried to explain the process in few steps. Step 1: Go to transaction code: SEGW. Step 2: Click on 'New Project' icon, a new pop-up screen will appear, fill all the details and save either locally or give package where you want your project to be saved.

What is the use of OData in SAP ABAP? ›

Description. SAP OData is a standard Web protocol used for querying and updating data present in SAP using ABAP. In SAP, we use SEGW transaction code to create an OData Service. OData is used to define best practices that are required to build and consume RESTful APIs.

How many ways we can create OData service in SAP? ›

Creating an OData service you can use: (1) “Classical” ABAP (needed for ABAP platform <= 7.4), which comes with significant higher efforts. (2) “SAP Fiori programing model” (ABAP platform = 7.5. 4) or SAP BTP, Steampunk/RAP and CAP (SAP BTP) both using CDS views. (see openSAP Fiori-EA1, Week1, Unit 4).

How to set up OData in SAP? ›

Activate OData Services
  1. Log on to the SAP Fiori server backend using SAP GUI.
  2. Enter transaction Activate and Maintain Services (/N/IWFND/MAINT_SERVICE).
  3. Choose Add Service.
  4. For the System Alias field, use the value help to select the correct service.

Top Articles
Latest Posts
Article information

Author: Twana Towne Ret

Last Updated:

Views: 5595

Rating: 4.3 / 5 (44 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Twana Towne Ret

Birthday: 1994-03-19

Address: Apt. 990 97439 Corwin Motorway, Port Eliseoburgh, NM 99144-2618

Phone: +5958753152963

Job: National Specialist

Hobby: Kayaking, Photography, Skydiving, Embroidery, Leather crafting, Orienteering, Cooking

Introduction: My name is Twana Towne Ret, I am a famous, talented, joyous, perfect, powerful, inquisitive, lovely person who loves writing and wants to share my knowledge and understanding with you.