Show TOC

Extending an OData Service Using Service BuilderLocate this document in the navigation structure

Activities

Extend the OData services by customizing the generated source code using Redefine functionality in the SAP Gateway Service Builder (Service Builder-transaction SEGW).

Generated Model Provider Classes- An Overview

When redefining a service, a new OData service generates a new Model Provider Class (MPC), and a new Data Provider Class (DPC). The MPC includes the MPC of the source service, and the DPC inherits the DPC of the source service.

The image below depicts the dependency between the classes:



Figure 1: Classes

In the illustration above, two sets of classes (MPC A, and DPC A) are generated for the source service A, and another set of classes (MPC B, and DPC B) are generated for the target service B.

While the model represented by MPC A is included in the MPC B for the redefined service, the DPC generated for the target service is inherited from the DPC of the source service, (DPC_EXT B inherits from DPC B, which also inherits from DPC_EXT A). The model in the redefined service can be further enhanced in the extension class of the extended service (MPC_EXT B). The runtime behavior of the newly added properties, entities, function imports and associations can be handled in the data provider extension class of the extended service (DPC_EXT B).

Use Cases for Redefining Services

This section will explain the extensibility functionality based on specific use cases and an example. In the base service (ZSALES_ORDER_EXAMPLE_SRV), there are three entity types SalesOrder, SalesOrderItems and SalesOrderProvider and an association SalesOrderSalesOrderItems. This service will be redefined and the new properties and entity types will be added in the redefined service.

The following are the use cases:

  • Use case 1: Adding a new property to an existing entity

  • Use case 2: Adding a new entity

  • Use case 3: Adding a new Function import

  • Use case 4: Adding an association and a navigation property

In the description of the use cases, we refer to the following example service, ZSALES_ORDER_EXAMPLE, which contains three entity sets:

  • SalesOrderSet: Data of sales orders (header)

  • SalesOrderItemSet: Data of items ordered

  • SalesOrderProviderSet

For our example, you will extend the source service by creating a new project, ZEXTEND_SALES_ORDER_EXAMPLE, following these steps:

  1. Create a new project ZEXTEND_SALES_ORDER_EXAMPLE which is referred to as the target service. See Creating a Service Builder Project for reference.

  2. Right click on the Data Model folder and select Redefine Start of the navigation path OData Service (SAP GW) End of the navigation path from the context menu.

    The Wizard Step 1 of 2: Redefine Service appears.

  3. In the Select Service region, enter the technical name of the service you wish to redefine in the Technical Service Name field. Alternatively, you can also use the input help available for this field.

    Note

    If the metatdata of the selected service resides in another system, then select Metadata to be fetched from an external system. in the Target System for Metadata. On selection of the Metadata to be fetched from an external system the RFC Destination field becomes editable to select the RFC destination of the external system. Input help is also available for this field.

  4. Click Next to continue.

    The Wizard Step 2 of 2: Redefine Service opens.

  5. Select the required artifacts and click Finish. See Redefining OData Service ( SAP GW) to understand the artifacts selection logic.

Refer Redefining OData Services (SAP GW) cook book for reference.

Use Case 1: Adding a New Property to an Existing Entity

The required process for adding a new property to your target service, ZEXTEND_SALES_ORDER_EXAMPLE, depends on how the service is implemented.

In the sections that follow, you will find explanations for the following:

  • Service implemented with MOVE command and entity bound to DDIC structure

  • Entity bound to a DDIC structure

    1. Open the Entity Type to check if it has the ABAP Structure Type Name assigned to it.

      OR

      Open the Define_ Entity Name Method in either the _MPC_EXT or _MPC from the Runtime Artifacts folder and check if the following code snippet is available.

      lo_entity_type->bind_structure( iv_structure_name   = 'SFLIGHT'
                                      iv_bind_conversions = 'X' ). "#EC NOTEXT
       
  • Entity not bound to a DDIC structure

  • The entity in the data model is not connected to a data dictionary (DDIC) structure

Service implemented with MOVE command and entity bound to DDIC structure

The section describes the process for extending an entity in a model that is connected to a Data Dictionary (DDIC) structure.

When the connected DDIC structure matches the data source structure (or its attributes by name), and the service has been implemented using the MOVE command, (either single MOVE, or MOVE-CORRESPONDING) to assign a value to ER_ENTITY, it will be sufficient to extend the DDIC structure, and to extend the model as described in steps 1 to 3 of the section, “The Entity in the Data Model is Connected to a Data Dictionary Structure”, without changing the code.

Below is an example code for the entity set, SALES_ORDER_ITEM Get Entity, where the MOVE command is used,(MOVE ls_et_order_item TO er_entity, to fill the er_entity; once the structure is extended, it is automatically moved in the code.

METHOD salesorderitemss_get_entity.
*-------------------------------------------------------------
*Data declaration
*-------------------------------------------------------------
DATA lv_sales_order_id TYPE zif_zsales_order_get=>char25.
DATA lv_sales_order_item TYPE zif_zsales_order_get=>char25.DATA et_order_item TYPE zif_zsales_order_get=>zsales_order_item_table.
DATA ls_et_order_item TYPE LINE OF zif_zsales_order_get=>zsales_order_item_table
DATA ls_converted_keys LIKE er_entity.
DATA lv_source_entity_set_name TYPE string.
*-------------------------------------------------------------
*Map the runtime request to the RFC - Only mapped attributes
*-------------------------------------------------------------
*Get all input information from the technical request context object
io_tech_request_context->get_converted_keys(
IMPORTING
es_key_values = ls_converted_keys
).
*Maps key fields to function module parameters
lv_source_entity_set_name = io_tech_request_context->get_source_entity_set_name( ).
lv_sales_order_item = ls_converted_keys-salesorderitempos.
lv_sales_order_id = ls_converted_keys-salesorderid.
*-------------------------------------------------------------
*Call RFC function module
*-------------------------------------------------------------
TRY.
CALL FUNCTION 'ZSALES_ORDER_GET'
EXPORTING
iv_sales_order_item = iv_sales_order_item
iv_sales_order_id = iv_sales_order_id
IMPORTING
et_order_item = et_order_item
EXCEPTIONS system_failure = 1000 message
lv_exc_msg
OTHERS = 1002.
*-------------------------------------------------------------------------*
* - Post Backend Call -
*-------------------------------------------------------------------------*
* Map properties from the backend to the SAP Gateway output response structure
* In GetEntity operation, we support only read for the first entry in the response table
READ TABLE et_order_item INTO ls_et_order_item INDEX 1.
MOVE ls_et_order_item TO er_entity.
ENDMETHOD.
 

Ensure that, the new property (ABAP field name) name is the same as the name of the data source attribute.

Note

If the service has not been implemented using the MOVE or MOVE-CORRESPONDING commands, the DPC (extension class) of the extended service has to be redefined to provide the runtime data for the newly added properties.

Entity bound to a DDIC structure

You enhance the structure by adding a new attribute to the DDIC structure. For the new attribute, you must create a new property in the specific entity of the model.

Prerequisites: The DDIC can be enhanced.

Do the following to extend an entity in a model that is connected to a DDIC structure:

  1. Follow these steps to add a new field to the DDIC structure

    1. Enter the transaction SE11, and choose Data Type, and then enter the name of the structure you want to enhance

    2. Click Display. In our example, the structure is, ZSALES_ORDER_ITEM.

    3. In the Dictionary: Maintain Structure screen, click GoTo in the menu bar, and select Append Structure (F5) to create the append structure with the additional fields.

      If you have already appended to the structure you can extend it. For example, we created an append structure called, ZVALUE and added fields NETVALUE and CURRENCY to it.

    4. When you add the fields to the structure, rename the fields using your own suffix or prefix to prevent naming conflicts.

    5. Add a new property for the new field to the entity of the model in the service builder.

      In the target service, add the new property to entity of the model and save it.

      In our example, we added the fields, NetValue and Currency, to the entity type, SALESORDER.

    6. Save and generate the project for the target service. The new classes of the target service are generated.

    7. To change the implementation in DPC, update the code for the methods of the specific extended entity in the DPC (extension) class for the target service, ZEXTEND_SALES_ORDER_EXAMPLE.

      To update the methods, you can use one of the following options:

      • Redefine the methods for the Create, Read, Update, Delete, Query (CRUDQ) operations of the specific Entity. Copy the code from the original method and update it by providing the additional fields.

      • Call the super class and add the additional fields in your code. If the service has been implemented using SAP tools, such as, Explicit Enhancement Point or BADI, you can use it instead of redefining the class method.

        Note

        Conversion Exits work without any code change for the newly added properties.

Entity not Bound to a DDIC Structure

The following is the process for extending an entity in a model that is not connected to a DDIC structure:

  1. Add a new property to the entity type and generate the service, ZEXTEND_SALES_ORDER_EXAMPLE. In our example, we added a new property, Supplier, to the entity type, SALESORDER.

  2. Redefine the dispatching methods (methods that route to the type CRUDQ methods) of the operations:

  3. Open the DPC extension class of the target service, ZEXTEND_SALES_ORDER_EXAMPLE, and redefine the dispatching methods for Create, Read, Update, and Query (CRUQ) operations for the extended entity:

    • /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITY

    • /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_ENTITY

    • /IWBEP/IF_MGW_APPL_SRV_RUNTIME~UPDATE_ENTITY

    • /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITYSET

  4. For the dispatching method of each operation, enhance the code for the extended entity set and call the super method for all other entities.

    Note

    Optional: To be consistent with SAP development, follow the next step and build the typed methods, and in the dispatching method route to the typed methods

  1. Copy the typed methods for the CRUDQ operations that have been assigned to the entity set you want to extend.

  2. Example of method names for the operations:

    • Provide a new name, by adding a suffix or prefix, such as, _EXT. In the example, we copied the methods in the source service, ZSALES_ORDER_EXAMPLE, to the new methods in the target service, and added the suffix, _EXT.

  3. Update the method interfaces with the model provider class (MPC extension) types in your new project.

  4. Once you have the new methods, you can update their interfaces.

    Note

    The new methods are not inherited; therefore you can update their interfaces.

    For each method, copy the type structure in the MPC extension class of the source service, ZSALES_ORDER_EXAMPLE, and replace the type structure in the MPC extension class in the target service, ZEXTEND_SALES_ORDER_EXAMPLE .

Make changes to the methods of the operations as follows:

  1. Change type of ER_ENTITY in CREATE operation:

    • In the source service, ZSALES_ORDER_EXAMPLE, the MPC extension class displays, ZCL_ZSALES_ORDER_EXAMP_MPC=>TS_SALESORDER.

    • In the target service, ZEXTEND_SALES_ORDER_EXAMPLE, edit the MPC extension class to, ZCL_ZEXTEND_SALES_ORDE_MPC=>TS_SALESORDER .

  2. The DELETE operation: No changes are required for this operation.

    • In the source service, ZSALES_ORDER_EXAMPLE, the MPC extension class displays as, ZCL_ZSALES_ORDER_EXAMP_MPC=>TS_SALESORDER.

    • In the target service, ZEXTEND_SALES_ORDER_EXAMPLE, edit the MPC extension class to, ZCL_ZEXTEND_SALES_ORDE_MPC=>TS_SALESORDER.

  3. Change type of ER_ENTITYSET in Read (GET_ENTITYSET) operation.

    • In the source service, ZSALES_ORDER_EXAMPLE, the MPC extension class displays as, ZCL_ZSALES_ORDER_EXAMP_MPC=>TT\_SALESORDER.

    • In the target service, ZEXTEND_SALES_ORDER_EXAMPLE, edit the MPC extension class to, ZCL_ZEXTEND_SALES_ORDE_MPC=>TT_SALESORDER.

  4. Change type of ER_ENTITYSET in QUERY (GET_ENTITYSET) operation.

    • In the source service, ZSALES_ORDER_EXAMPLE, the MPC extension class displays as, ZCL_ZSALES_ORDER_EXAMP_MPC=>TT\_SALESORDER.

    • In the target service, ZEXTEND_SALES_ORDER_EXAMPLE, edit the MPC extension class to, ZCL_ZEXTEND_SALES_ORDE_MPC=>TT_SALESORDER.

  5. Change type of ER_ENTITY in UPDATE operation.

    • In the source service, ZSALES_ORDER_EXAMPLE, the MPC extension class displays as, ZCL_ZSALES_ORDER_EXAMP_MPC=>TT_SALESORDER.

    • In the target service, ZEXTEND_SALES_ORDER_EXAMPLE, edit the MPC extension class to, ZCL_ZEXTEND_SALES_ORDE_MPC=>TT_SALESORDER.

  6. Update the code in the methods, and provide the additional fields.

    You have two main options to update the code. The option you choose depends on the logic you want to implement:

    1. Call the original method of the entity operation; and then provide the code for the additional field.

    2. Copy the code for the method of the specific Entity Set, and the specific operation, from the original method; and update the code for the additional fields.

      If you choose to implement the first option, you will be using SAP code with your own code for the additional fields. The disadvantage is that, it you may call the backend twice; once for the SAP provided fields, and then again for the additional fields.

Redefine the Dispatching Methods

The next process is to redefine each dispatching method in the DPC (extension) class. There are typed methods with MPC type, and dispatching methods. At runtime the dispatching methods, one method per each CRUDQ operation, are called with a generic interface that dispatches the call to specific typed methods. The specific call is based on the Entity Set name. In each dispatch method, verify that the specific entity is the extended entity, and then route the entity to the new methods, if not, route it to a super dispatching method.

Below is an example code for Get Entity:
METHOD /iwbep/if_mgw_appl_srv_runtime~get_entity.
DATA salesorderset_get_entityset
TYPE zcl_zextend_sales_orde_mpc=>ts_salesorder.
DATA lv_entityset_name TYPE string.
DATA lr_entity TYPE REF TO data.
lv_entityset_name = io_tech_request_context->get_entity_set_name( ).
CASE lv_entityset_name.
*------------------------------------------------------------------------- *
* EntitySet - SalesOrderSet
*-------------------------------------------------------------------------
* WHEN 'SalesOrderSet'.
* Call the entity set generated method
salesorderset_get_ent_ext(
EXPORTING iv_entity_name = iv_entity_name
iv_entity_set_name = iv_entity_set_name
iv_source_name = iv_source_name
it_key_tab = it_key_tab
it_navigation_path = it_navigation_path
io_tech_request_context = io_tech_request_context
IMPORTING er_entity = salesorderset_get_entityset ).
IF salesorderset_get_entityset IS NOT INITIAL.
* Send specific entity data to the caller interface
copy_data_to_ref(
EXPORTING
is_data = salesorderset_get_entityset
CHANGING
cr_data = er_entity ).
ELSE.
* In case of initial values - unbind the entity reference er_entity = lr_entity.
ENDIF.
*-------------------------------------------------------------------------*
* Other enteties => call SAP model
*-------------------------------------------------------------------------
WHEN OTHERS.
TRY.
CALL METHOD super->/iwbep/if_mgw_appl_srv_runtime~get_entity
EXPORTING
iv_entity_name = iv_entity_name
iv_entity_set_name = iv_entity_set_name
iv_source_name = iv_source_name
it_key_tab = it_key_tab it_navigation_path = it_navigation_path
io_tech_request_context = io_tech_request_context
IMPORTING
er_entity = er_entity.
CATCH /iwbep/cx_mgw_busi_exception.
* todo
CATCH /iwbep/cx_mgw_tech_exception.
* todo
ENDTRY.
ENDCASE.
ENDMETHOD.
 

Use Case 2: Adding a New Entity

The following are the processes for adding a new entity to extend the OData service:

  1. In your target service, ZEXTEND_SALES_ORDER_EXAMPLE, create and add the new entity (Products), and then generate the project.

  2. Manually create new methods for the CRUDQ operations you require for the newly created entity.

    You can also copy existing methods generated for another entity and use it to update your new entity, and add the relevant code.



    Figure 2: Creating New Methods
  3. Make sure to change the Associated type of the Method Parameters of the newly created methods.



    Figure 3: Method Parameters
  4. Redefine the dispatching method.

    The dispatching methods are inherited from the DPC source service, and these methods do not recognize the new entity; therefore you must redefine these methods in your target service.

    METHOD /iwbep/if_mgw_appl_srv_runtime~get_entityset.
     
      DATA productsset TYPE zcl_zextend_sales_orde_mpc=>tt_products.
      DATA lv_entityset_name TYPE string.
      DATA lr_entity TYPE REF TO data.
      lv_entityset_name = io_tech_request_context->get_entity_set_name( ).
     
      CASE lv_entityset_name.
    *------------------------------------------------------------------------- *
    * entityset - productsset
    *-------------------------------------------------------------------------
        WHEN 'ProductsSet'.
    * call the entity set generated method
          productsset_get_entityset(
          EXPORTING iv_entity_name = iv_entity_name
          iv_entity_set_name = iv_entity_set_name
          iv_source_name = iv_source_name
          it_filter_select_options = it_filter_select_options
          it_order = it_order
          is_paging = is_paging
          it_key_tab = it_key_tab
          it_navigation_path = it_navigation_path
          iv_filter_string = iv_filter_string
          iv_search_string = iv_search_string
          io_tech_request_context = io_tech_request_context
          IMPORTING et_entityset = productsset ).
     
          IF productsset IS NOT INITIAL.
            copy_data_to_ref(
            EXPORTING
            is_data = productsset
            CHANGING
            cr_data = er_entityset ).
          ELSE.
    * in case of initial values 
          ENDIF.
     
        WHEN OTHERS.
          TRY.
              CALL METHOD super->/iwbep/if_mgw_appl_srv_runtime~get_entityset
                EXPORTING
                  iv_entity_name           = iv_entity_name
                  iv_entity_set_name       = iv_entity_set_name
                  iv_source_name           = iv_source_name
                  it_filter_select_options = it_filter_select_options
                  it_order                 = it_order
                  is_paging                = is_paging
                  it_key_tab               = it_key_tab
                  it_navigation_path       = it_navigation_path
                  iv_filter_string         = iv_filter_string
                  iv_search_string         = iv_search_string
                  io_tech_request_context  = io_tech_request_context
                IMPORTING
                  er_entityset                = er_entityset.
            CATCH /iwbep/cx_mgw_busi_exception.
    * todo
            CATCH /iwbep/cx_mgw_tech_exception.
    * todo
          ENDTRY.
      ENDCASE.
     
    ENDMETHOD. 
     

Use Case 3: Adding a New Function Import

The following are the enhancement processes for extending an OData service by adding a new function import to the data model:

  1. Add a new function import into the model.

  2. Manually redefine the function import method, </IWBEP/IF_MGW_CORE_SRV_RUNTIM =>EXEC_SERVICE_OPERATION> , and write your own code for the newly added function import and call the super class </IWBEP/IF_MGW_CORE_SRV_RUNTIM =>EXEC_SERVICE_OPERATION>.

Use Case 4: Adding an Association and a Navigation Property

The following are the enhancement processes for extending an OData service by adding an association and a navigation property:

  1. In the target service, add the new association, navigation property, and referential constraint to the data model.

  2. Update the code in the query and read operations of the target entity.

Boundary Conditions

The following are the enhancement processes for extending an OData service by adding a new function import to the data model:

  1. In the redefined service, RFC mapping editor cannot be used for DPC generation.

  2. If your entity is bound to a structure in the base service, it should not be bound to the new structure in the redefined service.

  3. Redefining a composed service is not supported.

  4. DIC binding is not supported when the Backend system is different from the IW_BEP & IW_FND system.

  5. If an entity is bound to a DDIC structure, the ABAP type of the property cannot be modified from the ABAP type editor in SEGW.

  6. Redefining a service from another BEP system is not supported.