ABAP OData CRUD Operations - A Complete Step by Step Guide
A practical walkthrough of building OData services in SAP using SEGW, MPC, and DPC with real ABAP code
Introduction
If you’re working with SAP Fiori, UI5, or any external application that talks to SAP backend, you’ve already heard of OData. OData (Open Data Protocol) is the standard REST-based protocol that acts as a bridge between your SAP ABAP backend and frontend technologies like Fiori apps, mobile apps, or even Postman.
In this post, I’ll walk you through building a fully working OData service from scratch covering all five CRUD operations with real ABAP code from a live SAP project.
What You’ll Learn
- How to set up an OData service in SEGW
- The role of MPC and DPC classes
- How to implement GET (single & all), POST, PUT, and DELETE
- Key terms and concepts you must know
Key Concepts Before We Begin
Before diving into the code, let’s quickly understand the important building blocks:
Term What It Does OData REST protocol for SAP ↔ Frontend communication SEGW Transaction to create and manage OData services MPC Model Provider Class defines the service structure DPC Data Provider Class handles actual data logic MPC_EXT / DPC_EXT Extension classes safe place for your custom code Entity One record (like one employee row) EntitySet A collection of all records it_key_tab SAP provided table holding URL key values io_data_provider SAP provided object to read POST/PUT request body er_entity Response structure for a single record et_entityset Response table for multiple records
Why MPC_EXT and DPC_EXT ? SAP recommends writing all custom logic only in the
_EXTclasses. If you ever regenerate the service in SEGW, the base classes get overwritten but your_EXTcode stays safe.
Step 1 : Create the OData Service in SEGW
Transaction: SEGW
Open SEGW and click the Create icon to create a new project (e.g., ZODATA_63)
Create an Entity Type -this defines your data structure. Example: employee_details with properties EmpId, EmpName, Dept, Salary
Mark EmpId as the Key field
- The EntitySet (
employee_detailsSet) is created automatically - Click Generate Runtime Artifacts — this creates the MPC and DPC classes automatically
Assign a package and save
To check whether the structure has been created
Automatically structure will be created inside the program alone
Best Practice: Even though creating a structure is optional, always create one explicitly. When you provide a table directly, MPC auto generates a structure but doing it manually gives you better visibility and control.
Step 2 : Register the Service
Transaction: /n/iwfnd/maint_service
- Search for your service name:
ZODATA_63 - Click Add Selected Services to register it
- Assign a system alias
- Test with the URL format:
/sap/opu/odata/sap/ZODATA_63_SRV/employee_detailsSetThis is the EntitySet name in the URL , get this from the SEGW project.
Another Method : Link to gateway client
Step 3 : GET_ENTITYSET (Read All Records)
This method fetches all records from the database and fills the et_entityset response table. It is triggered by a simple GET request to the EntitySet URL.
Go to SEGW -> runtime artifacts
Right click the get_entityset
Goto /n/iwfnd/maint_service and search the service name zodata_63
From here only we are taking the entity set name
after the zodata_63_srv/ Type employee_detailsSet and click on execute to see the output
GET ALL DATA’S : GETENTITY SET , to get all the records ie fetch all the employees
METHOD EMPLOYEE_DETAILS_GET_ENTITYSET.DATA: lt_employee TYPE TABLE OF z63_employee, "Internal table - stores multiple rows
ls_entity TYPE zcl_zodata_63_mpc=>ts_employee_details. "Work area - one row SELECT * FROM z63_employee INTO TABLE lt_employee. "Read all recordsLOOP AT lt_employee INTO DATA(ls_employee).
CLEAR ls_entity. "Clear previous loop data
ls_entity-emp_id = ls_employee-emp_id. "Copies database data to OData structure.
ls_entity-emp_name = ls_employee-emp_name.
ls_entity-dept = ls_employee-dept.
ls_entity-salary = ls_employee-salary.
APPEND ls_entity TO et_entityset. "Add to OData response
ENDLOOP.
ENDMETHOD.
Save and Activate then again goto SAP Gateway client
Test URL:
/sap/opu/odata/sap/ZODATA_63_SRV/employee_detailsSetStep 4 : GET_ENTITY (Read Single Record)
This fetches one record using a key value from the URL. SAP Gateway automatically parses the key from the URL and stores it in it_key_tab before calling this method.
GETENTITY - GET SINGLE RECORD - Used to fetch one employee using key.
Get Asmamalica’s stories in your inbox
Join Medium for free to get updates from this writer.
same as before redefine the get_entity and write the method then save and activate
METHOD EMPLOYEE_DETAILS_GET_ENTITY. "This method is automatically triggered when a GET request for a single record is called.DATA: lv_empid TYPE z63_employee-emp_id,
ls_data TYPE z63_employee."Extract key from URL → it_key_tab is auto filled by SAP Gateway
READ TABLE it_key_tab INTO DATA(ls_key)
WITH KEY name = 'EmpId'." “it_key_tab -> It contains key values from URL.
IF sy-subrc = 0.
lv_empid = ls_key-value.” Moves employee ID from URL key table into variable.
ENDIF.
"Fetch matching record from DB
SELECT SINGLE * FROM z63_employee INTO ls_data
WHERE emp_id = lv_empid. IF sy-subrc = 0.
er_entity-emp_id = ls_data-emp_id.
er_entity-emp_name = ls_data-emp_name.
er_entity-dept = ls_data-dept.
er_entity-salary = ls_data-salary.
ENDIF.ENDMETHOD.
Test URL:
/sap/opu/odata/sap/ZODATA_63_SRV/employee_detailsSet('01')Step 5 : CREATE_ENTITY (Insert New Record)
Called when a POST request is sent with a JSON body. The incoming payload is read using io_data_provider→read_entry_data() this object is automatically provided by SAP Gateway. You do not create it manually.
METHOD employee_details_create_entity.DATA: ls_input TYPE zcl_zodata_63_mpc=>ts_employee_details, "OData payload holder
ls_db TYPE z63_employee. "DB structure"Read JSON body sent from frontend/Postman
io_data_provider->read_entry_data(
IMPORTING
es_data = ls_input ).Reads JSON payload sent from Gateway Client/UI.and the datas are stored in ls_input , moving the odata data to db structure"Map OData payload → DB structure
ls_db-emp_id = ls_input-emp_id. ” Copies Employee ID from payload to DB structure.
ls_db-emp_name = ls_input-emp_name.
ls_db-dept = ls_input-dept.
ls_db-salary = ls_input-salary. INSERT z63_employee FROM ls_db. "Insert into DBIF sy-subrc = 0. "checking for insertion successful
er_entity-emp_id = ls_db-emp_id."Returns inserted Employee ID to response.
er_entity-emp_name = ls_db-emp_name.
er_entity-dept = ls_db-dept.
er_entity-salary = ls_db-salary.
ENDIF.ENDMETHOD.
Test URL:
/sap/opu/odata/sap/ZODATA_63_SRV/employee_detailsSetBefore testing POST: Go to SICF, find your OData service, double click it, and save. Also verify in SEGW that all CRUD operation checkboxes are ticked under Service Implementation.
Double click on the odata name
click save and also in segw check whether all the required functional are ticked
Now check in segw
Step 6 : UPDATE_ENTITY (Modify a Record)
Called via PUT request. The key (EmpId) comes from the URL via it_key_tab, and the new field values come from the request body via io_data_provider. Never confuse the two sources.
Update - Put - to update the single record
This method executes when PUT request is sent.
METHOD EMPLOYEE_DETAILS_UPDATE_ENTITY.DATA: ls_input TYPE zcl_zodata_63_mpc=>ts_employee_details,” Declares structure to hold incoming OData payload.
ls_db TYPE z63_employee,” Database work area structure.Used to update database table.
lv_empid TYPE z63_employee-emp_id.” Variable to store Employee ID from URL."Key from URL
READ TABLE it_key_tab INTO DATA(ls_key) “Reads one row from internal table. Stores found row into work area LS_KEY
WITH KEY name = 'EmpId'.
IF sy-subrc = 0.
lv_empid = ls_key-value.
ENDIF. "New field values from request body
io_data_provider->read_entry_data(
IMPORTING es_data = ls_input ).
- what is io_data_provider
- IO_DATA_PROVIDER is an object automatically provided by SAP Gateway framework.You do NOT create it manually.
- SAP passes it automatically to methods like: create_entity and update_entity
- It is used to read incoming request payload data.
- SAP framework creates object and sends it automatically during request processing.
ls_db-emp_id = lv_empid. "ID always from URL
ls_db-emp_name = ls_input-emp_name. "Values from JSON body
ls_db-dept = ls_input-dept.
ls_db-salary = ls_input-salary. UPDATE z63_employee FROM ls_db. IF sy-subrc = 0.
er_entity-emp_id = ls_db-emp_id.
er_entity-emp_name = ls_db-emp_name.
er_entity-dept = ls_db-dept.
er_entity-salary = ls_db-salary.
ENDIF.
ENDMETHOD.
Step 7 : DELETE_ENTITY (Remove a Record)
Called via DELETE request. SAP Gateway parses the key from the URL, stores it in it_key_tab, and calls this method. You just read the key and delete.
DELETE ENTITY , Delete , This method is used to delete one employee record from database table.
METHOD EMPLOYEE_DETAILS_DELETE_ENTITY.“This method executes when DELETE request is sent.DATA: lv_empid TYPE z63_employee-emp_id,
ls_key TYPE /iwbep/s_mgw_name_value_pair. READ TABLE it_key_tab INTO ls_key
WITH KEY name = 'EmpId'.IF sy-subrc = 0.
lv_empid = ls_key-value.
ENDIF.
DELETE FROM z63_employee WHERE emp_id = lv_empid.
ENDMETHOD.“When the user sends a DELETE request using the URL /sap/opu/odata/sap/ZODATA_63_SRV/employee_detailsSet('01'), SAP Gateway automatically calls the DELETE_ENTITY method. The employee ID present in the URL is first stored inside the internal table IT_KEY_TAB. Using the READ TABLE statement, the program extracts the key value EmpId and stores it into the variable LV_EMPID. Finally, the DELETE statement uses this employee ID in the WHERE condition to remove the matching employee record from the database table Z63_EMPLOYEE."
Test URL (DELETE request):
/sap/opu/odata/sap/ZODATA_63_SRV/employee_detailsSet('01')When a DELETE request hits this URL, SAP Gateway extracts '01' from the URL, places it in it_key_tab under the name EmpId, and your code picks it up via READ TABLE.
Summary
Here’s a one Line recap of everything:
- SEGW → Build the ervice model and generate classes
- MPC_EXT → Define structure (rarely touched)
- DPC_EXT → Write all your CRUD logic here
- it_key_tab → Where URL keys land (GET, UPDATE, DELETE)
- io_data_provider → Where request body data lands (POST, PUT)
- er_entity → Send back a single record
- et_entityset → Send back all records
OData in ABAP can look intimidating at first, but once you understand that every HTTP verb maps to one ABAP method and that SAP Gateway handles all the routing and parsing for you it becomes very straightforward.
Final Thoughts
OData CRUD operations are not just about exposing data they provide a powerful and standardized way to interact with SAP backend records from any modern frontend, whether it’s Fiori, UI5, or even external tools like Postman.
Understanding how OData works along with SAP Gateway, SEGW project setup, and the MPC/DPC class architecture helps you build efficient, user friendly, and real time data integration solutions.
Mastering OData CRUD concepts can:
- Enable real-time database operations directly from frontend applications
- Improve user experience with seamless and responsive SAP integrations
- Reduce complexity compared to traditional BAPI or RFC based approaches
- Help you build reusable and maintainable OData services in SAP ABAP
- Strengthen your core ABAP skills in modern SAP development
This blog is written as a simple guide for beginners and a handy reference for real time OData CRUD implementation in SAP ABAP projects.
I’ll be documenting my SAP ABAP learning journey here follow along for more practical and beginner friendly insights.
Thanks for reading !








