2

We're using OData v4.0 and we're trying to get a nested call where we have a $filter and a $select and then an $expand. The $expand also has a $select. The $select and $expand work if they are not added in the same query.

For example; The $select by itself like this.

/adsTradeLineEventReserves?$filter=destTradeDocumentNo eq 'S*1249'&$select=carrierNo,destTradeDocumentNo

Results in

{
  "@odata.context": "https://*************/TEST/api/ADS/ADS/v1.0/$metadata#adsTradeLineEventReserves",
  "value": [
    {
      "@odata.etag": "W/\"JzE4OzU4NzkyNTAwODEyMzAyNDA1NzE7MDA7Jw==\"",
      "carrierNo": "",
      "destTradeDocumentNo": "S00001249"
    }
  ]
}

The $expand by itself like this.

/adsTradeLineEventReserves?$filter=destTradeDocumentNo eq 'S*1249'&$expand=adsReserveItemInventories

Results in

{
  "@odata.context": "https://*************/TEST/api/ADS/ADS/v1.0/$metadata#adsTradeLineEventReserves",
  "value": [
    {
      "@odata.etag": "W/\"JzE4OzU4NzkyNTAwODEyMzAyNDA1NzE7MDA7Jw==\"",
      "systemId": "df3fda84-b069-ed11-8a35-0022487ef089",
      "binCode": "C06",
      "ceLabelCode": "NOCU",
      "ceUnitOfMeasure": "KG",
      "carrierNo": "",
      "createdDateTime": "0001-01-01T00:00:00Z",
      "createdUserID": "",
      "destTradeDocDetLineNo": 0,
      "destTradeDocumentLineNo": 10000,
      "destTradeDocumentNo": "S00001249",
      "destTradeDocumentType": "Document",
      "adsReserveItemInventories": [
        {
          "@odata.etag": "W/\"JzE5Ozc0MjUwNTk4NzIyNTI3MjQ0ODUxOzAwOyc=\"",
          "id": "4274ce1e-4d50-ed11-8a2e-0022487ef089",
          "EntryNo": 6904,
          "ItemNo": "CAPYEL",
          "VariantCode": "",
          "LotNo": "10000746",
          "CarrierNo": "C00002085"
        },
        {
          "@odata.etag": "W/\"JzE5Ozk0OTcyMjQxNjc5MjEzODkxMzkxOzAwOyc=\"",
          "id": "5474ce1e-4d50-ed11-8a2e-0022487ef089",
          "EntryNo": 6905,
          "ItemNo": "CAPYEL",
          "VariantCode": "",
          "LotNo": "10000746",
          "CarrierNo": "C00002086"
        }
      ]
    }
  ]
}

But when I combine the $select and $expand it looks like this.

/adsTradeLineEventReserves?$filter=destTradeDocumentNo eq 'S*1249'&$select=carrierNo,destTradeDocumentNo&$expand=adsReserveItemInventories

This results in an invalid JSON structure as you can see.

{"@odata.context":"https://*************/TEST/api/ADS/ADS/v1.0/$metadata#adsTradeLineEventReserves","value":[{"@odata.etag":"W/\"JzE4OzU4NzkyNTAwODEyMzAyNDA1NzE7MDA7Jw==\"","carrierNo":"","destTradeDocumentNo":"S00001249"

The $expand is completely ignored and the invalid JSON is returned right after the $select. I've tried changing the order and put the $expand up front and the $select at the end. But it results in the same invalid JSON. I also tried removing the filter and adding a server-sided pagination but those two both result in the same invalid JSON.

I'm totally clueless what is going wrong. I expected the OData to return an error instead of an unfinished JSON.

BJNM
  • 63
  • 6

1 Answers1

1

Combining $select and $expand in the same request, is both supported and common. Your syntax is correct for an OData v4 compliant service so you should consult the vendor (OutSystems.com) for technical support.

The only times I have seen this is when there is a data related issue that means the serializer stalls or otherwise experiences an exception, as the output is incomplete, I suspect something similar is the case here.

As this is effectively an implementation issue, we can only speculate, however sometimes simply reversing the order of the query options or ensuring that all required properties are included in the $select will help avoid common implementation issues.

Good luck and please report back with your solution, it won't help the general OData community, but will be useful for other Out Systems users.

Chris Schaller
  • 13,704
  • 3
  • 43
  • 81
  • Although I agree with this answer, it's worth mentioning that it doesn't make much sense to expand a collection when we're not intending to select it. – Luis Gouveia Dec 10 '22 at 20:40
  • 1
    @LuisGouveia if you omit `$select` then you get the server _default_ selection, so all fields in many cases. There are times when you may not want all the fields in the root or a particular child level, to reduce the bytes, so you might deliberately select zero fields. It does seem like a very basic requirement for the vendor to get right though. – Chris Schaller Dec 10 '22 at 23:53