Netweaver Gateway Development

how to implement nested OData($expand query option) in SAP?



                    The $expand query option is very powerful and allows you to provide multiple entities and/or entity sets in one single service call, instead of performing several calls subsequently.
                      For $expand query to work an association or navigation property should be created.To know more about association refer Implement association.
                      In this tutorial we will create an association from our flight entity set to flight schedule entityset.Then we will implement get_expanded_entityset method.

Pre-requisites

  1. GET_ENTITYSET of flightset implemented already.(GET_ENTITYSET implementation)
  2. GET_ENTITY of flightset implemented already.(Refer OData Service Implementation for GET_ENTITY)
  3. FlightScheduleSet created by importing ddic structure SPFLI table(Please refer  my previous post step-by-step-gateway-odata-service)
Syntax


    
http://<host>:<port>/sap/opu/odata/SAP/ZTEST_ODATA_SRV_01/FlightSet?$expand=ToFlightSchedules


Steps

  1. First step is creating association.For this Open the service and click on edit button.Expand Data Model.Right click on Associations and click on create button.Association wizard will be opened.
  2. In the association wizard you have to give Association Name,Principal entity type name,Dependant entity type name,cardinality and Navigation Property name.Navigation Property name is used when accessing associated entity data in our OData url.(Create related navigation property check box will be checked by default).After entering values to these fields click next.
  3. You will land on step 2 of association wizard.Select dependent property and click next.Dependent property will be the key relating two entities.
  4. In step 3 select Principal entityset and dependant entityset and click finish.
  5. Finally our odata service should look like this.See navigation propery is added to flight entity set.Also an association and association set is created.Press generate button.
  6. Now open our ****_DPC_EXT class and go to edit mode.

  7. From inherited methods node find /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET and right click and press redefine.
  8. Its time for some coding.Paste below code inside GET_EXPANDED_ENTITYSET method.
  9.      data lv_entityset_name type string.
        data: begin of str_exp.
                include           type zcl_ztest_odata_01_mpc_ext=>ts_flight.
        data: toflightschedules type  zcl_ztest_odata_01_mpc_ext=>tt_flightschedule,
    
              end of str_exp.
    
        data: lt_expand   like  table of str_exp,
              ls_expand   like str_exp,
              ls_schedule type zcl_ztest_odata_01_mpc=>ts_flightschedule.
        data:it_flight   type  table of scarr,
             wa_flight   like line of it_flight,
             it_schedule type table of spfli,
             wa_schedule like line of it_schedule.
    
        constants: lc_expand_tech_clause type string value 'TOFLIGHTSCHEDULES'.
        lv_entityset_name = io_tech_request_context->get_entity_set_name( ).
    
        case lv_entityset_name.
          when 'FlightSet'.
            select * from scarr into corresponding fields of table it_flight.
            select * from spfli into table it_schedule.
            if sy-subrc = 0.
    
              loop at it_flight into wa_flight.
                move-corresponding wa_flight to ls_expand .
                loop at it_schedule into wa_schedule where carrid = wa_flight-carrid.
                  move-corresponding wa_schedule to ls_schedule.
                  append ls_schedule to ls_expand-toflightschedules.
                  clear ls_schedule.
                endloop.
                append ls_expand to lt_expand.
                clear ls_expand.
              endloop.
            endif.
        endcase.
        copy_data_to_ref(
      exporting
        is_data = lt_expand
      changing
        cr_data = er_entityset ).
    
        insert lc_expand_tech_clause into table et_expanded_tech_clauses.   
    
    
  10. Now we can test  in gateway client( /IWFND/GW_CLIENT).Our service url look like this.http://<host>:<port>/sap/opu/odata/SAP/ZTEST_ODATA_SRV_01/FlightSet?$expand=ToFlightSchedules.Press execute button.ToFlightSchedules is the navigation property.
see how to bind nested odata($expand query) in SAPUI5 Application
If you enjoyed this post, Please Share!!

10 comments :

  1. Hello Rajeesh,

    I am wondering will this logic suits if more than two entities should be expanded? For now I'm getting the error message: "RFC Error: The XML document that was read had an invalid format.", when testing with three entity sets.

    Thanks!

    ReplyDelete
    Replies
    1. Hi,
      It will work.I have tested it with a third entity called flightbookings.My code changes are below.
      //in structure section
      data: begin of str_exp.
      include type zcl_ztest_odata_01_mpc_ext=>ts_flight.
      data: toflightschedules type zcl_ztest_odata_01_mpc_ext=>tt_flightschedule,
      toflightbooking type zcl_ztest_odata_01_mpc_ext=>tt_flightbooking,
      end of str_exp.
      //in constant section
      constants: lc_expand_tech_clause type string value 'TOFLIGHTSCHEDULES,TOFLIGHTBOOKING'.
      //Also inside the main loop i have added one loop to get flight bookings

      Hope this helps

      Delete
  2. I have implemented my Service in similar way but the control is not going to get_expanded_entity or get_expended_entityset.
    Any pointers?

    ReplyDelete
    Replies
    1. Hi Indu,
      Have you made association between two entities?
      also check the structure
      data: begin of str_exp.
      include type zcl_ztest_odata_01_mpc_ext=>ts_flight.
      data: toflightschedules type zcl_ztest_odata_01_mpc_ext=>tt_flightschedule,
      //see data: above...
      end of str_exp.

      also check if you have added

      insert lc_expand_tech_clause into table et_expanded_tech_clauses.
      in last line..

      sorry for late reply..:)

      Delete
  3. HI. I'm trying to call GET_EXPANDED_ENTITYSET without using GET_ENTITY or GET_ENTITYSET like this...
    /LibCredSet?$filter=VpCodcliente eq '0001002278' &$expand=NAVSAFRA01
    and on GW client or browser is working but when i try to use inside SAPUI5 binding the 'filter=VpCodcliente eq '0001002278' is not recognizable...So i must use GET_ENTITY and GET_ENTITYSET before $EXPAND?

    Thanks!!!!

    ReplyDelete
    Replies
    1. If it is working in GW it will work with sapui5 also...
      try using binding like this
      items="{
      path : '/LibCredSet',
      parameters:{expand : 'NAVSAFRA01'},
      filters : [
      { path : 'VpCodcliente', operator : 'EQ', value1 : '0001002278'}
      ]
      }"

      Delete
  4. Hi,
    Thanks for your nice blog,
    I have redefined GET_EXPANDED_ENTITYSET and GET_EXPANDED_ENTITY..
    GET_EXPANDED_ENTITYSET is working its returning the values ,..
    but when tried using the below URI ::
    /sap/opu/odata/SAP/ZSER_NAME/SalesHeaderSet(Vbeln='0000000001')?$expand=OrderToItem&$format=json
    its returning the empty values..
    Can you pls help me where i did mistake ..

    ReplyDelete
    Replies
    1. The result set is
      "d" : {
      "__metadata" : {
      "id" : "http://bfs4hana-4.spartaconsulting.com:2000/sap/opu/odata/SAP/ZSER_NAME/SalesHeaderSet('')",
      "uri" : "http://bfs4hana-4.spartaconsulting.com:2000/sap/opu/odata/SAP/ZSER_NAME/SalesHeaderSet('')",
      "type" : "ZSER_NAME.SalesHeader"
      },
      "Vbeln" : "",
      "Erdat" : null,
      "Erzet" : "PT00H00M00S",
      "Ernam" : "",
      "Netwr" : "0.000",
      "Waerk" : "",
      "Vkorg" : "",
      "Vtweg" : "",
      "Kunnr" : "",
      "OrderToItem" : {
      "results" : [

      ]
      }
      }
      }

      Delete
    2. Check putting an external breakpoint inside GET_EXPANDED_ENTITY method. The problem may be inside the loop if there is one. Also check if both structures are similar the one going to front end and one coming from backend (ordertoitem).
      Try debugging

      Delete
  5. Hi, I have also the same problem (result is empty) but the methods are working properly. When I made debug, in the method copy_data_to_ref(), lt_expand is full of data and is cr_data is assigned successfully. But the result is empty

    ReplyDelete

Powered by Blogger.