2

I was trying to implement the $expand query option for an Odata Service in SEGW... I basically have UsersSet and ProductsSet... and the relation is m:n between users and products (Users can have multiple products, and products can belong to multiple users).

I want to create /UsersSet?$expand=ToProducts where all products are shown that belong to a user. For that, I have created an intermediary table "UsersProducts" with properties "userid" and "productid" to reflect the m:n association.

I basically created an "extended" deep entity ty_usersproducts in my MPC_EXT class, corresponding to user properties and an array of products (that belong to that user).

  types: BEGIN OF TY_USERPRODUCTS ,
    INCLUDE TYPE ZCL_ZALM_FS_APP_MPC_EXT=>ts_users,
    toproducts TYPE STANDARD TABLE OF ZCL_ZALM_FS_APP_MPC_EXT=>ts_products WITH DEFAULT KEY,
    END OF TY_USERPRODUCTS.

      types: TT_USERPRODUCTS TYPE STANDARD TABLE OF TY_USERPRODUCTS.

I then extended the method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET. in the DPC_EXT class:

  method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET.

    DATA : lt_deep_userProd TYPE TABLE OF zcl_zalm_fs_app_MPC_EXT=>ty_userproducts, "Deep Entity Type
           ls_deep_userProd TYPE zcl_zalm_fs_app_MPC_EXT=>ty_userproducts,         "Deep Entity Type
           ls_product        TYPE zcl_zalm_fs_app_MPC_EXT=>ts_products,
           ls_reluprod TYPE zcl_zalm_fs_app_mpc_ext=>ts_reltableusersproducts,
           lt_products TYPE TABLE OF zcl_zalm_fs_app_MPC_EXT=>ts_products.

    DATA(lv_expand) = io_tech_request_context->get_expand( ).
    DATA(lv_top) = io_tech_request_context->get_top( ).
    DATA(lv_skip) = io_tech_request_context->get_skip( ).
    DATA numTop TYPE int8.
    numTop = lv_top.
    DATA numSkip TYPE int8.
    numSkip = lv_skip.

    IF lv_top IS INITIAL.
      numTop = 10.
    ENDIF.
* Based on the entity set
    IF iv_entity_set_name = 'UsersSet'.
      SELECT * FROM zalm_fs_users
        INTO TABLE @DATA(lt_users)
        UP TO @numTop ROWS.

      IF sy-subrc = 0.
        SELECT * FROM zalm_fs_reluprod
          INTO TABLE @DATA(lt_reluprod)
          FOR ALL ENTRIES IN @lt_users
          WHERE userid = @lt_users-id.
      ENDIF.
      IF lt_users IS NOT INITIAL AND lt_reluprod IS NOT INITIAL.
        LOOP AT lt_users into DATA(ls_user).


          ls_deep_userProd-include = CORRESPONDING #( ls_user ).
          SELECT * FROM zalm_fs_reluprod
            INTO TABLE @DATA(lt_reluprod2)
            WHERE userid = @ls_user-id.

          LOOP AT lt_reluprod2 into ls_reluprod.
            SELECT SINGLE * FROM ZALM_FS_PRODUCTS
              WHERE id = @ls_reluprod-productid
              INTO @DATA(uprod).
              APPEND uprod TO ls_deep_userProd-toproducts.
         ENDLOOP.
         APPEND ls_deep_userprod TO lt_deep_userprod.
         CLEAR ls_deep_userprod-toproducts.

      ENDIF.

* For converting the data in the deep structure to the output format
      CALL METHOD me->/iwbep/if_mgw_conv_srv_runtime~copy_data_to_ref
        EXPORTING
          is_data = lt_deep_userprod
        CHANGING
          cr_data = er_entityset.

  ENDIF.
  endmethod.

The code seems to be correct in the debugger.. it returns the user properties and the products table in the deep entity... the only problem is.. in the SEGW Gateway service to test things out... the output does not appear there, so what is returned in the er_entityset does not correspond to my deep structure that I put together above in the sql statement.. I wonder why?

Somehow in the debugger, not only get_expanded_entityset method is executed... after returning out of the method, some other methods like read_entityset are also executed.. maybe that is the problem?

Or second idea... I head that you had to name the properties in your deep entity model class in a specific way... eg the products collection would need to have the same name as the navigation (or was it association) name that you defined in SEGW? I'm not sure what exactly the problem is.. any ideas?

Suncatcher
  • 10,355
  • 10
  • 52
  • 90
MMMM
  • 3,320
  • 8
  • 43
  • 80
  • Did you create the associations and navigation entities in SEGW for the parent entity to the child entities? Do the child-entities have key fields that match all the key fields of the parent entity (in name, type and value)? – Philipp May 04 '23 at 14:16
  • By the way, I implemented several $expand-capable oData services and I never implemented the `GET_EXPANDED_ENTITYSET` method. The framework was always capable of doing that on its own just based on my implementations of `GET_ENTITYSET` and the navigation property I defined in SEGW. – Philipp May 04 '23 at 14:22
  • What do you mean with 'the output does not appear there, like u want'? can you do an example. ```GET_EXPANEDE_ENTITYSET``` is the way to go. To prevent that the get_entityset method is getting called you have to fill your techclause e.g. ```lv_tech_clause = YOUR_EXPANDED_CLAUSE. INSERT lv_tech_clause into table et_expanded_tech_clauses.``` you can àlso concante if you expand to multiply assosications. – Jünge alles May 04 '23 at 18:51
  • @Philipp oops yeah, you were actually right, I didn't see it in the xml format. But in json the "ToProducts" and "ToCompanies" are actually embedded in the same single users('id') document.. I think I will post an answer to that.. I am just wondering if it works also with the solution from Jünge, didn't try it out yet... I just found many custom get_expanded_entityset redifinition solutions on the web and was trying to reproduce that, but it seems to work already from the framework side so yet no real need for it. – MMMM May 05 '23 at 13:34

1 Answers1

2

Ok I think I found the "solution"... I somehow overlooked it, but it seems the framework is capable and supports on itself the $expand parameter implementation if you implemented the get_entity and get_entityset method before...

Maybe I will try out other solutions and try to implement get_expanded_entityset manually and post an update sometime because I wasted a lot of time for it, but for now it works with framework support only..

So for my query

/sap/opu/odata/SAP/ZALM_FS_APP_SRV/UsersSet('1')?$expand=ToProducts,ToCompanies&$format=json

I get:

{
  "d" : {
    "__metadata" : {
      "id" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/UsersSet('00001')",
      "uri" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/UsersSet('00001')",
      "type" : "ZALM_FS_APP_SRV.Users"
    },
    "Id" : "00001",
    "Uuid" : "3423e00f-b5c2-4f2c-bf88-baceca11c5f4",
    "Firstname" : "Isabel",
    "Lastname" : "Zapletal",
    "Fullname" : "Eddi Engel",
    "Gender" : "männlich",
    "Username" : "Annabelle12",
    "Email" : "Mick87@hotmail.com",
    "Avatar" : "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/221.jpg",
    "Password" : "4GYJ5LYoXrEmpZU",
    "Birthdate" : "30.4.1988",
    "Registeredat" : "2023-02-26T10:49:56.165Z",
    "Phone" : "97-1365-5739",
    "Jobtitle" : "Corporate Brand Executive",
    "Jobtype" : "Agent",
    "Profileinfo" : "Hi, my name is Bo Neuendorf.\n    I was born in Tue May 14 1968 03:04:13 GMT+0100 (Mitteleuropäische Sommerzeit) and I am currently working as a Chief Branding Officer at Rossberg Gruppe.\n    Check out my site on exzessiv-erwachsener.ch and contact me any time at +79 799 514 8382. Vitae unde tempora dolore a magnam. Consequatur deleniti veniam unde porro voluptates harum exercitationem cum reprehenderit. Eos ullam dignissimos laborum veniam voluptas consequuntur. Deleniti tempora sed veritatis ipsam laborum blanditiis. Vero vitae distinctio aut ea nihil. Soluta unde inventore.",
    "Country" : "Kroatien",
    "County" : "Buckinghamshire",
    "City" : "Neu Giuliadorf",
    "Streetaddress" : "Am Quettinger Feld 977 Zimmer 152",
    "Latitude" : "8",
    "Longitude" : "-71",
    "Zipcode" : 99171,
    "Maybe" : "Yeah I'm here!",
    "Companyid" : "00020",
    "ToCompanies" : {
      "__metadata" : {
        "id" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/CompaniesSet('00020')",
        "uri" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/CompaniesSet('00020')",
        "type" : "ZALM_FS_APP_SRV.Companies"
      },
      "Id" : "00020",
      "Uuid" : "75853702-b707-4301-b742-94da20d36735",
      "Companyname" : "Birkemeyer-Rosenbauer",
      "Catchphrase" : "Reduced coherent system engine",
      "Sector" : "Agriculture",
      "Buzz" : "scale virtual platforms",
      "Maybe" : "",
      "Companylogo" : "https://loremflickr.com/800/600/logo",
      "ToUsersSet" : {
        "__deferred" : {
          "uri" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/CompaniesSet('00020')/ToUsersSet"
        }
      }
    },
    "ToProducts" : {
      "results" : [
        {
          "__metadata" : {
            "id" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/ProductsSet('00085')",
            "uri" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/ProductsSet('00085')",
            "type" : "ZALM_FS_APP_SRV.Products"
          },
          "Id" : "00085",
          "Title" : "LouisWill Men Sunglasses",
          "Description" : "LouisWill Men Sunglasses Polarized Sunglasses UV400 Sunglasses Day Night Dual Use Safety Driving Night Vision Eyewear AL-MG Frame Sun Glasses with Free Box for Drivers",
          "Price" : 50,
          "Discountpercentage" : "11.27",
          "Rating" : "4.98",
          "Stock" : 92,
          "Brand" : "LouisWill",
          "Category" : "sunglasses",
          "Thumbnail" : "https://i.dummyjson.com/data/products/85/thumbnail.jpg",
          "Images" : "https://i.dummyjson.com/data/products/85/1.jpg",
          "UsersSet" : {
            "__deferred" : {
              "uri" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/ProductsSet('00085')/UsersSet"
            }
          }
        },
        {
          "__metadata" : {
            "id" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/ProductsSet('00008')",
            "uri" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/ProductsSet('00008')",
            "type" : "ZALM_FS_APP_SRV.Products"
          },
          "Id" : "00008",
          "Title" : "Microsoft Surface Laptop 4",
          "Description" : "Style and speed. Stand out on HD video calls backed by Studio Mics. Capture ideas on the vibrant touchscreen.",
          "Price" : 1499,
          "Discountpercentage" : "10.23",
          "Rating" : "4.43",
          "Stock" : 68,
          "Brand" : "Microsoft Surface",
          "Category" : "laptops",
          "Thumbnail" : "https://i.dummyjson.com/data/products/8/thumbnail.jpg",
          "Images" : "https://i.dummyjson.com/data/products/8/1.jpg",
          "UsersSet" : {
            "__deferred" : {
              "uri" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/ProductsSet('00008')/UsersSet"
            }
          }
        },
        {
          "__metadata" : {
            "id" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/ProductsSet('00015')",
            "uri" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/ProductsSet('00015')",
            "type" : "ZALM_FS_APP_SRV.Products"
          },
          "Id" : "00015",
          "Title" : "Eau De Perfume Spray",
          "Description" : "Genuine  Al-Rehab spray perfume from UAE/Saudi Arabia/Yemen High Quality",
          "Price" : 30,
          "Discountpercentage" : "10.99",
          "Rating" : "4.70",
          "Stock" : 105,
          "Brand" : "Lord - Al-Rehab",
          "Category" : "fragrances",
          "Thumbnail" : "https://i.dummyjson.com/data/products/15/thumbnail.jpg",
          "Images" : "https://i.dummyjson.com/data/products/15/1.jpg",
          "UsersSet" : {
            "__deferred" : {
              "uri" : "http://adeps4p0.saplab.3as-cloud.de:50000/sap/opu/odata/SAP/ZALM_FS_APP_SRV/ProductsSet('00015')/UsersSet"
            }
          }
        }
      ]
    }
  }
}

So "ToCOmpanies" and "ToProducts" are embedded.

But you have to define the associations and navigation properties in SEGW: enter image description here

MMMM
  • 3,320
  • 8
  • 43
  • 80