Affects Version/s: V4.0_CS01
Fix Version/s: V4.0_CSD03
Consumers using $levels=max MUST be prepared to handle entity references in cases were a circular reference would occur otherwise.
Providers must solve circular dependency by injecting an entity reference somewhere in the circular dependency.Consumers using $levels=max MUST be prepared to handle entity references in cases were a circular reference would occur otherwise. Providers must solve circular dependency by injecting an entity reference somewhere in the circular dependency. Accepted: https://www.oasis-open.org/committees/download.php/50877/odata-meeting-54_on-20131001-minutes.html#odata-536
https://www.oasis-open.org/committees/download.php/50920/odata-v4.0-wd04-part1-protocol-2013-10-03.docx(2)https://www.oasis-open.org/committees/download.php/50900/odata-v4.0-wd04-part1-protocol-2013-10-03.docx https://www.oasis-open.org/committees/download.php/50920/odata-v4.0-wd04-part1-protocol-2013-10-03.docx(2 ) Accepted: https://www.oasis-open.org/committees/download.php/50924/odata-meeting-55_on-20131003-minutes.html#odata-532
Current documents don't describe how to deal with cases where expansion using $levels, especially the $levels=max case, runs into a circular reference.
Optional solutions to this might be:
1 - Omitting the navigation property that would otherwise result in the circular reference
2 - Include the entity but no longer expand anything that was already expanded previously (very hard to track potentially)
3 - Inject an entity reference if odata.allow-enityreferences preference has been specified or return an invalid request otherwise
4 - A combination of 2 and 3 where an entity reference would be injected if the odata.allow-entityreferences preference had been specified or the entity, without any further expansions, would be returned otherwise
Issues with these proposals:
- The request is valid, the cycle could exist at one point and not at the other, so invalid request response would be flatout incorrect
- Not expanding an entity further is at a minimum confusing as well as one would not be able to deduce from looking at it that the reason some navigation properties didn't get included was because of the circular reference
- Always using a reference, even without the odata.allow-entityreferences preference, is not an option as consumers might not be prepared to deal with those
With all that in mind one might come to the conclusion, as we did in an initial discussion, that simply omitting the navigation property causing the circular reference would be the least astonishing solution. That would be fine for to 1 relationships but not for collections as you'd have one entry less in that case?
Entity references overall seem to be the best solution here but we don't necessarily like the link with the odata.allow-entityreferences preference. This, i.c.w. the fact that it's not really a bad request anyway, lead us to propose that consumers that use $levels=max ought to be able to deal with entity references respectively of the use of the preference. Without the odata.allow-entityreferences preference an entity reference would only get injected if a circular reference would occur otherwise while with the preference presumably reference would get injected wherever a previously expanded entity might get referenced. This distinction is also important because the selected and expanded properties don't always have to line up between the various expands of the same entity.