Create Odata for CRUD operations:
Prerequisite: You must be well versed in OOABAP
What is Data model in Odata?
In OData, the data model defines the structure and relationships between different data entities. Here's a breakdown with an example to explain the key elements clearly:
1. Entity Type:
- Definition: An entity type is a blueprint for an entity, defining its structure (fields, data types, and lengths). It is similar to a structure in ABAP.
- Example: Let's assume you're modeling data for a customer. The entity type for a customer might look like this:
Customer Entity Type:
- CustomerID (Type: CHAR10)
- CustomerName (Type: CHAR50)
- City (Type: CHAR30)
- Country (Type: CHAR30)
This entity type defines the structure of a single customer.
2. Entity Set:
- Definition: An entity set is a collection of records based on an entity type. It is similar to an internal table in ABAP, where multiple records of a specific entity type are stored.
- Example: The entity set for customers would store multiple customer records:
Customer Entity Set:
[
{ CustomerID: "C001", CustomerName: "John Doe", City: "New York", Country: "USA" },
{ CustomerID: "C002", CustomerName: "Jane Smith", City: "London", Country: "UK" }
]
3. Association:
- Definition: An association defines the relationship between two entity types. For example, you can have an association between a Customer and Order entity types.
- Example: A customer can have multiple orders, so we create an association between the Customer entity type and the Order entity type.
Association Example:
- Customer (Entity Type) ↔ Order (Entity Type)
- Relationship: One customer can have many orders.
4. Association Set:
- Definition: An association set represents the relationship between two entity sets, which are collections of records. This is used to link multiple customers to their respective orders.
- Example: If we have an Order Entity Set that stores multiple orders, an association set would link each customer in the Customer Entity Set to their corresponding orders in the Order Entity Set.
Association Set Example:
- Customer Entity Set ↔ Order Entity Set
- For example:
- Customer C001 is associated with orders O001, O002
- Customer C002 is associated with order O003
Example Scenario:
Imagine you have two entity types: Customer and Order.
Customer Entity Type:
- CustomerID (Type: CHAR10)
- CustomerName (Type: CHAR50)
Order Entity Type:
- OrderID (Type: CHAR10)
- OrderDate (Type: DATS)
- CustomerID (Type: CHAR10) – Foreign key linking to Customer
Association between Customer and Order:
- Each Customer can have multiple Orders.
- The association helps you connect a customer with their specific orders.
Example in Code:
- Customer Entity Set:
[
{ CustomerID: "C001", CustomerName: "John Doe" },
{ CustomerID: "C002", CustomerName: "Jane Smith" }
]
- Order Entity Set:
[
{ OrderID: "O001", OrderDate: "2023-09-01", CustomerID: "C001" },
{ OrderID: "O002", OrderDate: "2023-09-10", CustomerID: "C001" },
{ OrderID: "O003", OrderDate: "2023-09-05", CustomerID: "C002" }
]
The association set links the Customer Entity Set with the Order Entity Set, ensuring that orders are correctly tied to their corresponding customers.
Summary of Key Concepts:
- Entity Type: Defines the structure of a single entity, like a structure in ABAP.
- Entity Set: A collection of entities (records), like an internal table.
- Association: The relationship between two entity types (like foreign key relationships in a database).
- Association Set: The relationship between two entity sets.
This data model is key to developing OData services, as it allows you to fetch and represent structured data and their relationships in a RESTful manner.
Important methods and parameters for CURD methods:
1. Create (CREATE_ENTITY method)
- Purpose: To create a new record in the back-end system.
- Key Parameters:
- IO_DATA_PROVIDER: This is an interface that captures the input record values sent from the front-end application. It provides methods to retrieve data sent in the request.
- ER_ENTITY: This parameter is used to send the newly created record as output back to the front-end after successful creation.
- Example Usage:
In a customer management OData service, when a new customer is created in the front-end app, this method will take the input (like CustomerID, CustomerName, etc.) from IO_DATA_PROVIDER, create a new customer in the database, and return the newly created record using ER_ENTITY.
2. Update (UPDATE_ENTITY method)
- Purpose: To update an existing record.
- Key Parameters:
- IO_DATA_PROVIDER: Captures the input record values that need to be updated. This includes both the key and non-key fields.
- ER_ENTITY: After updating the record in the back-end system, the updated record is sent back to the front-end using this parameter.
- Example Usage:
If a customer’s details are updated, this method would take the modified values (e.g., CustomerName, City) from IO_DATA_PROVIDER and update the corresponding record in the database.
3. Delete (DELETE_ENTITY method)
- Purpose: To delete an existing record.
- Key Parameter:
- IT_KEY_TAB: This table holds the key field(s) of the record that needs to be deleted. The front-end passes the key field (like CustomerID), and this parameter captures it.
- Example Usage:
When a customer is deleted in the front-end app, CustomerID is passed in IT_KEY_TAB. The back-end system deletes the corresponding customer record.
4. Get (GET_ENTITY method)
- Purpose: To retrieve a single record from the back-end system.
- Key Parameters:
- IT_KEY_TAB: This table captures the input key field(s) (like CustomerID) that uniquely identify the record to be fetched.
- ER_ENTITY: This parameter sends the output (the fetched record) back to the front-end.
- Example Usage:
If a user wants to view the details of a specific customer, CustomerID is passed to IT_KEY_TAB, and the method retrieves the customer record and sends it via ER_ENTITY.
5. Get Multiple Records (GET_ENTITYSET method)
- Purpose: To retrieve a collection of records from the back-end system.
- Key Parameters:
- IV_FILTER_STRING: This captures any filters applied by the front-end app (e.g., fetch all customers from a specific city). This string is processed to extract filter conditions.
- ET_ENTITYSET: This is used to send multiple records (a collection of entities) back to the front-end.
- Example Usage:
If the user wants to fetch all customers from a specific country, the country code filter is passed in IV_FILTER_STRING, and ET_ENTITYSET will return all customer records that match this condition.
Practical Workflow:
1. Create: Use CREATE_ENTITY() to add a new customer to the database.
2. Update: Use UPDATE_ENTITY() to modify existing customer data.
3. Delete: Use DELETE_ENTITY() to remove a customer record.
4. Get (Single Record): Use GET_ENTITY() to retrieve details of a specific customer by ID.
5. Get (Multiple Records): Use GET_ENTITYSET() to fetch a list of customers, with optional filtering (e.g., by city, country).
Let’s start the coding:
In this I’m going to use CRUD methods for the custom table ZUSERINFO. I’ve already created the table and creating the data model using this table.
In SAP OData development, we write code for CRUD operations, like CREATE_ENTITY(), in the DPC_EXT class instead of other runtime artifacts because of the following key reasons:
1. Extensibility and Customization:
- DPC stands for Data Provider Class, and SAP automatically generates the DPC class when you create an OData service. This class contains the methods for CRUD operations, but these are empty templates meant for standard handling.
- The DPC_EXT (Data Provider Class Extension) is provided to allow developers to extend and implement custom logic without modifying the auto-generated standard class.
- Why use DPC_EXT: Modifying the original DPC class directly is not recommended because it is a generated class, and any updates or regenerations of the service could overwrite your custom logic. The DPC_EXT class is designed specifically for customization and will not be overwritten by the system.
2. Separation of Concerns:
- By using DPC_EXT, you maintain a clear separation between the standard code (in the DPC class) and your custom business logic (in the DPC_EXT class). This makes the service more maintainable and future-proof.
3. Enhancement Framework Compatibility:
- SAP follows an enhancement framework where custom code should be placed in extension classes rather than the core standard classes. The DPC_EXT class is intended to act as an enhancement layer on top of the generated DPC class.
- This is similar to the enhancement framework in ABAP, where you do not modify the standard SAP code but use enhancements or extensions to implement custom logic.
4. Lifecycle Management:
- During the lifecycle of an OData service (when updates, changes, or regenerations occur), the system may regenerate the DPC class. If custom logic is written in the DPC class, it risks being overwritten.
- The DPC_EXT class remains untouched during regenerations or updates to the OData service, so your custom logic stays intact.
5. OData Method Inheritance:
- DPC_EXT is a subclass of DPC, and it inherits all the methods (including CREATE_ENTITY, UPDATE_ENTITY, etc.) from DPC. You can override the methods that require custom logic in DPC_EXT while keeping the standard ones untouched.
- When the service runtime calls the CREATE_ENTITY() method, it first looks for the implementation in DPC_EXT. If it finds an overridden method there, it executes that. Otherwise, it falls back to the default behavior in the parent DPC class.
Example Workflow:
1. DPC Class (Auto-generated):
- Contains methods like CREATE_ENTITY() with basic templates (usually empty).
- Do not modify these methods, as this class can be regenerated and overwrite your changes.
2. DPC_EXT Class (For Custom Logic):
- You write custom code inside methods like CREATE_ENTITY() here. For example, fetching data from the front-end, performing validations, and then creating an entity in the back-end.
- This class is where you extend the functionality and implement the actual business logic.
- You write code in the DPC_EXT class because it is designed specifically for customization and extensibility, ensuring that any changes you make will not be lost during service regeneration or updates. The DPC class remains the system-generated standard layer, while the DPC_EXT class is where you safely add your business-specific logic.
This separation ensures smooth service maintenance and versioning, adhering to SAP's best practices for OData service development.
Redefine the CREATE_ENTITY method.
Code:
Method.
Data wa type zcl_zodata_project5_mpc=>ts_employee.
io_data_provider => read_entry_data ( Importing es_data = wa ).
Insert into zuserinfo values wa.
If sy-subrc eq 0.
er_entity = wa.
endif.
endmethod.
Write this custom logic in DPC_EXT class - CREATE_ENTITY method.
Let's break down the code in the CREATE_ENTITY method of the DPC_EXT class step by step. The objective of this code is to create a new entry in the zuserinfo table based on the data received from the front-end application.
1. Define a Work Area:
DATA wa TYPE zcl_zodata_project5_mpc=>ts_employee_table. "defined work area for ER_ENTITY.
- Explanation:
- The variable wa is declared as a work area of type ts_employee_table, which is an ABAP structure defined in your OData service metadata class (ZCL_ZODATA_PROJECT5_MPC).
- ts_employee_table represents the structure of the entity type (like Employee) from your data model. This structure defines the fields (such as EmployeeID, Name, etc.) that you will use to store the data from the front-end and pass to the back-end.
2. Read Input Data from the Front-End:
io_data_provider->read_entry_data( IMPORTING es_data = wa ).
- Explanation:
- The io_data_provider is a built-in interface that holds the incoming data from the front-end (the data sent in the OData request).
- The method read_entry_data reads the incoming data and imports it into the work area wa.
- The es_data = wa part means that the incoming data is now stored in the structure wa, which contains the field values provided by the front-end, such as an employee’s name, ID, or other details.
3. Insert Data into the Database Table:
INSERT INTO zuserinfo VALUES wa.
- Explanation:
- This statement inserts the data in wa into the database table zuserinfo, which is a custom table in SAP that stores employee information or other user-related details.
- INSERT INTO zuserinfo VALUES wa means:
- SAP tries to insert the contents of the wa work area into the corresponding columns of the zuserinfo table. Each field in the work area corresponds to a column in the table.
- If all mandatory fields are populated correctly and no duplicate keys exist, this will create a new record in zuserinfo.
4. Check for Successful Insertion:
IF sy-subrc EQ 0.
- Explanation:
- sy-subrc is a system field that stores the return code of the last operation. In this case, it captures the result of the INSERT statement.
- If sy-subrc = 0, the insertion was successful. Any non-zero value means an error occurred (e.g., a duplicate entry or missing field).
5. Return the Newly Created Entity to the Front-End:
er_entity = wa.
- Explanation:
- If the record was successfully inserted into zuserinfo, the newly created entity is sent back to the front-end application using the parameter er_entity.
- This allows the front-end to get confirmation and see the newly created entry.
6. Complete the Conditional Block:
ENDIF.
Summary of the Code Workflow:
1. Declare the work area (wa) based on the structure of your OData entity (employee data in this case).
2. Read input data from the front-end request using io_data_provider->read_entry_data(). This fills the work area wa with the data sent by the front-end (such as employee information).
3. Insert the data into the database table (zuserinfo) using the INSERT INTO statement.
4. Check if the insertion was successful using sy-subrc. If the return code is 0, it indicates a successful insert.
5. Send the created entity back to the front-end using the er_entity parameter.
This code effectively handles the creation of a new entry in the zuserinfo table and returns the newly created data to the front-end application for confirmation.
GET_ENTITYSET, CREATE_ENTITYSET, UPDATE_ENTITY, DELETE_ENTITY methods will be updated in the future post.
Select your entityset and enter the single username or single validation to retrieve the data because we implemented only GET_ENTITY.
Execute.
You’ll get the confirmation status code 200.
Your data will be shown in the right side of the window. For security reasons I haven’t take the full screenshot.
Fetched values.
Click use as a request. It will copy the response into request. In the request you can provide the new values.
Entries updated into the table.
In this post we implemented GET_ENTITY and CREATE_ENTITY for custom table. In future I’ll update remaining CRUD methods.
Stay tuned,
Happy coding.