focusing on beginners, I am writing this blog to explain about how to create OData service and consume OData service to UI5 application (through VSCode) and to work on CURD operations from UI5 Application to backend ABAP HANA Server (On Premises) in detail.
Info: – Here I am using SAP GUI 7.50 Version. if you are
running with older version please download and install with SAP GUI 7.50 Version for better understand this blog.
Let’s begin from OData service creation
Note: –
Please do follow the number orders and square boxes as mentioned in images as RedColor.
Before start be ready with database table otherwise create it in SE11 – Tcode
This is the database table which I have created and will perform CRUD Operation from the UI5 Application.
Step 1:
Go to SEGW – Tcode and click on Create project and provide valid Project name and description and click on Local object it will create new project.
now Expand the project and right click on Data Model project nav to import then click on DDIC Structure
Now provide proper name as Entity Type Name and import the database table by name of table as you created earlier and click on next
Select check box for the field selection on entity and click on next
Now make any field as primary key it can be one or more but mandatorily and click on Finish
Now your database table will be assigned to OData project successfully. But you can’t access all fields from the database table for the you need to redefine the methods.
Click on generate runtime objects and it will retain all your defaults methods to your OData project.
Now double click on ZCL_YOUR_PROJECT_NAME_DPX_EXT(left side) and double click on ZCL_YOUR_PROJECT_NAME_DPX_EXT from Runtime artifacts section to redefine all your methods.
Now you will see the screen of all your classes methods and go to Method section click on inherited Methods and nav to YOURENTITYNAME_GET_ENTITYSET Method, right click on it nav to Redefine option and it will open window to write your logic(clear the commented code and write code as given the following code and respective Methods).
Make sure it should be in change mode and after implementing new logic for GET_ENTITYSET method. Save (Ctrl+S) it and Activate (Ctrl+F3)
Now repeat the same steps for following methods. for GET_ENTITY, CREATE_ENTITY,DELETE_ENTITY and UPDATE_ENTITY,
GET_ENTITY (for reading single record from table)
* Fetch Single record based on the key in the URI
DATA : wa_key TYPE /IWBEP/s_MGW_NAME_VALUE_PAIR.
* Read the Key from URI
READ TABLE IT_KEY_TAB INTO wa_key WITH KEY name = 'Id'.
IF sy-subrc EQ 0.
SELECT SINGLE * FROM zmd_user_table
INTO CORRESPONDING FIELDS OF er_entity
WHERE Id EQ wa_key-value.
ENDIF.
CREATE_ENTITY (for creating new record)
* Create a record
DATA : wa_osuerdata TYPE zcl_zmd_odatacrud_mpc=>ts_zuserdata.
* Read the data from Request body
io_data_provider->read_entry_data(
IMPORTING
es_data = wa_osuerdata
).
MOVE-CORRESPONDING wa_osuerdata TO er_entity.
MODIFY zmd_user_table FROM wa_osuerdata.
UPDATE_ENTITY (to update particular record)
DATA : ls1 TYPE ZCL_ZMD_ODATACRUD_MPC=>ts_zuserdata.
io_data_provider->read_entry_data(
IMPORTING
es_data = ls1
).
* CATCH /iwbep/cx_mgw_tech_exception. "
UPDATE zmd_user_table FROM ls1.
DELETE_ENTITY (to delete the record)
DATA : LS2 TYPE /IWBEP/S_MGW_NAME_VALUE_PAIR.
"READING TABLE "
READ TABLE IT_KEY_TAB INTO LS2 WITH KEY name = 'Id'.
"DELETING THE RECORD "
DELETE FROM zmd_user_table WHERE Id = LS2-VALUE.
Save and Activate, Now come back to SEGW home screen by clicking back button and Click on generate runtime objects and nav to Service Maintenance and double click on it and Register Service till then Registration Status will be known.
now the Registration Status will be updated, now click on SAP Gateway Client (if any warnings popup means just click on Yes ) it will navigating to Gateway Client.
here select the EntitySet that your created and click on Execute it will fetch all records from the table.
Now you will see the all the records that your created for the table. And returns the HTTP Status code 200 if the GET_ENTITYSET methods logic was properly. Otherwise, Status code will be 401.
Step 2: OData CRUD Operations from UI5 application to SAP S/4 HANA Server (onPremise)
this is my OData from the backend which I have created (refer the Database table image from the beginning) and consumed it in my UI5 application.
View1.view.xml
<mvc:View controllerName="odatacrud.controller.View1"
xmlns:mvc="sap.ui.core.mvc" displayBlock="true"
xmlns="sap.m" xmlns:myform="sap.ui.layout.form">
<App id="_IDGenApp1">
<Page id="page">
<content>
<Table id="_IDGenTable1" items="{/ZUSERDATASet}" selectionChange="onSelect" mode="SingleSelectLeft" fixedLayout="false">
<columns>
<Column id="_IDGenColumn1">
<Text id="_IDGenText1" text="Employee Id"/>
</Column>
<Column id="_IDGenColumn2">
<Text id="_IDGenText2" text="Name"/>
</Column>
<Column id="_IDGenColumn3">
<Text id="_IDGenText3" text="Salary"/>
</Column>
<Column id="_IDGenColumn4">
<Text id="_IDGenText4" text="Age"/>
</Column>
</columns>
<items>
<ColumnListItem id="_IDGenColumnListItem1">
<cells>
<Text id="_IDGenText5" text="{Id}"/>
</cells>
<cells>
<Text id="_IDGenText6" text="{Name}"/>
</cells>
<cells>
<Text id="_IDGenText8" text="{Salary}"/>
</cells>
<cells>
<Text id="_IDGenText7" text="{Age}"/>
</cells>
</ColumnListItem>
</items>
</Table>
</content>
<Title id="_IDGenTitle1" text="Employee Details" class="myformTitle"></Title>
<myform:SimpleForm id="cMyform" editable="true" >
<myform:content>
<Label id="_IDGenLabel1" text="Emp_Id"/><Text id="_IDGenText9" text="{Id}"/>
<Label id="_IDGenLabel2" text="Name"/><Text id="_IDGenText10" text="{Name}"/>
<Label id="_IDGenLabel4" text="Salary"/><Text id="_IDGenText12" text="{Salary}"/>
<Label id="_IDGenLabel5" text="City"/><Text id="_IDGenInput5" text="{City}"/>
</myform:content>
</myform:SimpleForm>
<footer>
<Bar id="_IDGenBar1">
<contentRight>
<Button id="_IDGenButton1" text="Create" press="oCreateEmpPopup" type="Emphasized"/>
<Button id="_IDGenButton" text="Read" press="oSearchEmpPopup" type="Emphasized"/>
<Button id="_IDGenButton2" text="Update" press="oUpdateEmpPopup" type="Emphasized"/>
<Button id="_IDGenButton3" text="Delete" press="oDeleteEmp" type="Negative"/>
</contentRight>
</Bar>
</footer>
</Page>
</App>
</mvc:View>
View1.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast",
"sap/m/MessageBox"
],
/**
* @param {typeof sap.ui.core.mvc.Controller} Controller
*/
function (Controller, MessageToast, MessageBox) {
"use strict";
return Controller.extend("odatacrud.controller.View1", {
onInit: function () {
},
onSelect:function(oEvent)
{
var sPath = oEvent.oSource._aSelectedPaths
sPath = sPath[0].split("/")
sPath = sPath[1]
var myForm = this.getView().byId("cMyform")
myForm.bindElement("/"+sPath)
this.oPath = sPath
},
oCreateEmpPopup:function(){
if(!this.oFragment)
{
this.oFragment = new sap.ui.xmlfragment("odatacrud.fragment.CreateForm",this)
this.getView().addDependent(this.oFragment)
this.oFragment.open()
}
else{
this.oFragment.open()
}
},
oCloseButton:function(){
this.oFragment.close()
this.oFragment.destroy(true)
this.oFragment = null
},
oUpdateEmpPopup:function(){
if(!this.oReadEmpFragment)
{
this.oReadEmpFragment = new sap.ui.xmlfragment("odatacrud.fragment.ReadFrom",this)
var myForm = sap.ui.getCore().byId("cFragmentMyform")
myForm.bindElement("/"+this.oPath)
this.getView().addDependent(this.oReadEmpFragment)
this.oReadEmpFragment.open()
}
else{
this.oReadEmpFragment.open()
}
},
oCloseReadButton:function()
{
this.oReadEmpFragment.close()
this.oReadEmpFragment.destroy(true)
this.oReadEmpFragment = null
},
oCreateEmp:function() // FOR CREATING NEW RECORD ************
{
var UserName = sap.ui.getCore().byId('_IDGenInput2').getValue()
var UserSalary = sap.ui.getCore().byId('_IDGenInput3').getValue()
var UserId=sap.ui.getCore().byId('_IDGenInput1').getValue()
var UserAge=sap.ui.getCore().byId('_IDGenInput4').getValue()
var UserCity=sap.ui.getCore().byId('_IDGenInput5').getValue()
var oAddEmpData={}
oAddEmpData.Name=UserName
oAddEmpData.Salary=UserSalary
oAddEmpData.Id=UserId
oAddEmpData.Age=UserAge
oAddEmpData.City=UserCity
this.getView().getModel().create("/ZUSERDATASet",oAddEmpData,{
method:"POST",
success:function (data){
MessageToast.show("Employee Created Successfully");
},
error: function (data){
MessageToast.show(data);
},
});
},
oUpdateEmp:function() // FOR UPDATING RECORD *************
{
var UserName = sap.ui.getCore().byId('_IDGenInput2').getValue()
var UserSalary = sap.ui.getCore().byId('_IDGenInput4').getValue()
var UserId=sap.ui.getCore().byId('_IDGenInput1').getValue()
var oAddEmpData={}
oAddEmpData.Name=UserName
oAddEmpData.Salary=UserSalary
this.getView().getModel().update("/ZUSERDATASet('" + UserId + "')",
oAddEmpData,{
method:"PATCH",
success:function (data){
MessageToast.show("Employee update Successfully with number");
},
error: function (data){
MessageToast.show(data);
}
});
},
oDeleteEmp:function() // FOR DELETING RECORD **************
{
this.oPath
this.getOwnerComponent().getModel().remove("/ZUSERDATASet('" + this.oPath.split("'")[1] + "')", {
method: "DELETE",
success: function (data) {
MessageToast.show("Customer deleted Successfully");
},
error: function (Error) {
sap.m.MessageToast.show(Error);
}
});
},
oSearchEmpPopup:function(){
if(!this.SearchEmp)
{
this.SearchEmp = new sap.ui.xmlfragment("odatacrud.fragment.SearchEmp",this)
this.getView().addDependent(this.SearchEmp)
this.SearchEmp.open()
}
else{
this.SearchEmp.open()
}
},
oReadEmp1:function() // FOR READING A SINGLE RECORD BY USING ID OF EMPLOYEE
{
var SearchInp = sap.ui.getCore().byId("_IDGenInput1").getValue()
this.getOwnerComponent().getModel().read("/ZUSERDATASet('" + SearchInp + "')", {
method: "DELETE",
success: function (data) {
MessageBox.success("ID :- "+data.Id+" "+"Name :- "+data.Name+" "+"Salary :- "+data.Salary);
},
error: function (Error) {
sap.m.MessageToast.show(Error);
}
});
},
oCloseSearchButton:function()
{
this.SearchEmp.close()
this.SearchEmp.destroy(true)
this.SearchEmp = null
}
});
});
Refer this Project structure for Views, Controllers, models and fragments
CreateForm.fragment.xml
<c:FragmentDefinition
xmlns="sap.m"
xmlns:c="sap.ui.core"
xmlns:myform="sap.ui.layout.form">
<Dialog id="_IDGenDialog1" contentWidth="500px">
<content>
<myform:SimpleForm id="_IDGenSimpleForm1" editable="true">
<myform:content>
<Label id="_IDGenLabel1" text="Emp_Id"/><Input id="_IDGenInput1" placeholder="Enter Employee Id"/>
<Label id="_IDGenLabel2" text="Name"/><Input id="_IDGenInput2" placeholder="Enter your Name"/>
<Label id="_IDGenLabel3" text="Salary"/><Input id="_IDGenInput3" placeholder="Enter your Salary"/>
<Label id="_IDGenLabel4" text="Age"/><Input id="_IDGenInput4" placeholder="Enter your Age"/>
<Label id="_IDGenLabel5" text="City"/><Input id="_IDGenInput5" placeholder="Enter your City"/>
</myform:content>
</myform:SimpleForm>
</content>
<customHeader>
<Bar id="_IDGenBar1">
<contentLeft>
<Text id="_IDGenText1" text="Add Employee"/>
</contentLeft>
<contentRight>
<Button id="_IDGenButton1" icon="sap-icon://decline" press="oCloseButton"/>
</contentRight>
</Bar>
</customHeader>
<buttons>
<Button id="_IDGenButton2" text="Add" icon="sap-icon://add" press="oCreateEmp" type="Emphasized"/>
</buttons>
</Dialog>
</c:FragmentDefinition>
ReadForm.fragment.xml
<c:FragmentDefinition
xmlns="sap.m"
xmlns:c="sap.ui.core"
xmlns:myform="sap.ui.layout.form">
<Dialog id="_IDGenDialog1" contentWidth="500px">
<content>
<myform:SimpleForm editable="true" id="cFragmentMyform">
<myform:content>
<Label id="_IDGenLabel1" text="Emp_Id"/><Input id="_IDGenInput1" value="{Id}" />
<Label id="_IDGenLabel2" text="Name"/><Input id="_IDGenInput2" value="{Name}" />
<Label id="_IDGenLabel4" text="Salary"/><Input id="_IDGenInput4" value="{Salary}"/>
</myform:content>
</myform:SimpleForm>
</content>
<customHeader>
<Bar id="_IDGenBar1">
<contentLeft>
<Text id="_IDGenText1" text="Employee information"/>
</contentLeft>
<contentRight>
<Button id="_IDGenButton1" icon="sap-icon://decline" press="oCloseReadButton"/>
</contentRight>
</Bar>
</customHeader>
<buttons>
<Button id="_IDGenButton2" text="Update" press="oUpdateEmp"/>
</buttons>
</Dialog>
</c:FragmentDefinition>
SearchEmp.fragment.xml
<c:FragmentDefinition
xmlns="sap.m"
xmlns:c="sap.ui.core"
xmlns:myform="sap.ui.layout.form">
<Dialog id="_IDGenDialog1">
<content>
<myform:SimpleForm id="_IDGenSimpleForm1" editable="true">
<Input id="_IDGenInput1" placeholder="Enter Emp_Id"/>
<Button id="_IDGenButton2" press="oReadEmp1" icon="sap-icon://search"/>
</myform:SimpleForm>
</content>
<customHeader>
<Bar id="_IDGenBar1">
<contentLeft>
<Text id="_IDGenText1" text="Search Employee"/>
</contentLeft>
<contentRight>
<Button id="_IDGenButton1" icon="sap-icon://decline" press="oCloseSearchButton"/>
</contentRight>
</Bar>
</customHeader>
</Dialog>
</c:FragmentDefinition>
Here are the sample output images. For Creating
Here are the sample output images. For Reading
Now I am going to read the same data from the database table by the ID of employee.
Here are the sample output images. For Updating
Here I have updated salary for the same record 90000 to 89999 of employee 501.
Here are the sample output images. For Deleting
Here I am deleting the employee from the records 108 .
Conclusion
In order to do normal CRUD operations should access records by ID. As I am modifying particular records by database table ID. By this I can change only single record with multiple fields for same in one sing HTTP request. Not multiple records.
Hope I find it will we be helpful. If any queries please welcome on comment sections.
Note: All the images are shown in this blog are the snapshots that taken from my PC only.