Dynamically populating list of expand clause based on navigation property name
The general approach for fetching a parent and its child entity data in a single OData call is by implementing GET_EXPANDED_ENTITY method of the Data Provider Class. This involves explicitly specifying which child entities can be retrieved along with parent entity through hard-coding of the navigation properties in the method implementation. This requires populating the data in the nested properties of the parent structure carrying the same name as navigation property names and then adding the navigation’s to standard exporting parameter ET_EXPANDED_TECH_CLAUSES to inform the framework that the expand clause has already been catered by custom implementation and there is no need to call the child entity sets.
In OData project the 3 entities (FormulaHeader, FormulaTerm and FormulaComponent) are modeled as below:
Entity 1: FormulaHeader
Entity 2: FormulaTerm
Entity 3: FormulaComponent
Association 1: FormulaHeader -> FormulaTerm (1:N)
Association 2: FormulaTerm -> FormulaComponent (1:N)
Navigation 1: FormulaTermSet (between FormulaHeader and FormulaTerm)
Navigation 2: FormulaComponentSet (between FormulaTerm and FormulaComponent)
This OData call would return FormulaHeader data for its specified key fields (DealGUID and FormulaGUID), its corresponding child entities FormulaTermSet and FormulaComponentSet in a single Gateway call through GET_EXPANDED_ENTITY method.
The main point here that needs to be taken care is that we need to tell the Gateway framework that we have expanded the FormulaHeader, FormulaTerm and FormulaComponent entities in a single entity set call and there is no need to call the child entity set to fetch the Formula Terms and Formula Component data. We can do this using parameter ET_EXPANDED_TECH_CLAUSES of GET_EXPANDED_ENTITY and append both the Navigation Property Name(FORMULATERMSET and FORMULATERMSET/FORMULACOMPONENTSET) in this exporting parameter, which will tell the gate way framework that the child entities have already been expanded and there is no need to call the child entity sets.
In this blog I provide an alternative approach where I dynamically generate and append the navigation property names in ET_EXPANDED_TECH_CLAUSES through recursion.
The below call of method GET_EXPANDED_TECH_CLAUSES is implemented in the GET_EXPANDED_ENTITY method of the data provider class.
zcl_common_odata_util=>get_expanded_tech_clauses( EXPORTING ir_expand = ir_expand it_children = ir_expand->get_children( ) CHANGING ct_expanded_tech_clauses = et_expanded_tech_clauses ).
Logic for the above method is as follows:
- Loop at all the child entities of the calling URL.
- Check if the calling entity has a parent or not.
- If it doesn’t have a parent e.g. in our case the 1st call to this method would not have a parent so only FORMULATERMSET would be appended as child entity’s navigation property name).
- If it has a parent e.g. in our case the 2nd call to this method would have parent as FORMULATERM for child entity FORMULACOMPONENT, so in that case parent’s navigation property name(FORMULATERMSET) and child entity’s navigation property name FORMULACOMPONENTSET would be appended to CT_EXPANDED_TECH_CLAUSES.
Above scenario explained with screenshots:
For the above scenario, when the specified URL is executed, GET_EXPANDED_TECH_CLAUSES method is called from the GET_EXPANDED_ENTITY method.
For the 1st call from GET_EXPANDED_ENTITY method, the call is for FormulaHeader to get its children and navigation property names.
In this case, the parent is blank and FORMULATERMSET is its child entityset with FORMULATERMSET as its navigation property name.
Thus, in the 1st call FORMULATERMSET is added in field CT_EXPANDED_TECH_CLAUSES.
For the 2nd call of GET_EXPANDED_TECH_CLAUSES method(as it is recursive in nature), the call is for FormulaTerm to get its children and navigation property names.
In this case, the parent is FORMULATERMSET and FORMULACOMPONENT is its child entityset with FORMULACOMPONENTSET as its navigation property name.
Thus, in the 2nd call FORMULATERMSET/FORMULACOMPONENTSET is added in the field CT_EXPANDED_TECH_CLAUSES.
Final result in CT_EXPANDED_TECH_CLAUSES is as follows:
As this method is being called in recursion, during the second call the parent entity is FORMULATERM and FORMULACOMPONENTSET is its child entityset.
The implementation of GET_EXPANDED_TECH_CLAUSES method can handle navigation of multi-level child entities as it is recursive in nature.
Also, the main advantage of this approach is that no hard-coding of the navigation property names and entities are involved. And it can cater to all entities and its child entities without any entity specific logic.
This approach also works. I tried the above approach for a few scenarios and it works for all.
Thanks for providing an alternative solution.