OData compliance
Sitecore Experience Commerce (XC) release 10.0 and later is based on Microsoft.AspNetCore.Odata version 7.3.1.
The Commerce Service API is based on the Open Data Protocol (OData). OData provides metadata that allows external systems to discover Commerce capabilities and data structures. OData also supports annotations on metadata, which provides basic validation requirements and enumerations so that smarter clients can prevalidate and provide drop-down support for enumerable properties.
Most Microsoft products can natively consume OData. For example, Excel can connect to an OData source allowing the use of Power Pivot or other Excel-based analytic tools to be easily integrated. Other Microsoft products, including Microsoft Dynamics AX, support OData in their service layers.
Controllers
Sitecore XC controllers inherit from the ODataController
class. The base class is CommerceODataController
, and is shown in the following example:
...
[Authorize(Policy = "RoleRequirement")]
public class ComerceODataController : ODataController, IActionFilter, IAzynActionFilter, IDisposable
ODataRoutes
ODataRoutes use the ODataRoute
attribute and the ODataRoutePrefix
attribute.
The ODataRoute attribute
The ODataRoute
attribute defines controller actions, for example:
[HttpGet]
[ODataRoute]
[EnableQuery(MaxExpansionDepth = 0)]
public async Task<IEnumerable<CommerceEnvironment>> Get()
[HttpGet]
[EnableQuery(MaxExpansionDepth = 0)]
ODataRoute("({Id})]
public async Task<IActionResult> Get([FromODataUri] string id)
If you do not specify a RouteName
, the action is available for both the CommerceAPI and the CommerceOps routes.
We recommend the use of MaxExpansionDepth = 0
in the EnableQuery
attribute for any GET
action where the expand filter is used for more than 2 levels.
ODataRoute attribute examples for controller actions
The following action is only available through the CommerceOps
route:
[HttpPost]
[ODataRoute("RunMinion", RouteName = CoreConstants.CommercepsApi)]
public <IActionResult RunMinion([FromBody] ODataActionParameters value)
The following action is only available through the CommerceAPI
route:
[HttpGet]
[ODataRoute("GetListMetadata(listName={listName})", RouteName = CoreConstants.CommerceAPI)]
public async Task<IActionResult> GetListMetadata([FromODataUri] string listName)
The following action does not specify a route and, as a result, is available through both the CommerceAPI
and the CommerceOps
routes:
[HttpPost]
[ODataRoute("AddPolicy")]
public async Task<IactionResult> AddPolicy([FromBody] ODataActionParameters value)
The ODataRoutePrefix attribute
For entity OData controllers, the ODataRoutePrefix
attribute specifies the prefix that is used for all actions of that controller. The ODataRoutePrefix
attribute value must match the entity set names.
In the following example, the ODataRoutePrefix
is based on the entity set defined as arg.EntitySet<CommerceEnvironment>("Environments")
:
...
[ODataRoutePrefx("Environments")]
public class EnvironmentsController : CommerceOdataController
The OData Model Builder
The ODataConventionModelBuilder
uses a strict discovery mechanism. Because the discovery mechanism is stricter, you must add your classes in the IEdmModel.
XC uses the following pipelines to build the IEdmModel:
-
IConfigureServiceApiPipeline
-
IConfigureOpsServiceApiPipeline
To facilitate the discovery of derived classes, you can use the following extensions to the ODataConventionModelBuilder:
-
AddCommerceComplexType
: this extension maps a CLR class and all its derived classes asComplexTypes
. This action is available through both the CommerceAPI route and the CommerceOps route.For example:
RequestResponsearg.AddCommerceCompletexType(typeof(Model)); arg.AddCommerceCompletexType(typeof(Policy)); arg.AddCompletexType(typeof(CommandMessage)); arg.AddCompletexType(typeof(EntityReference)); arg.AddCompletexType(typeof(Dictionary<string, string>)); arg.AddCompletexType(typeof(List<Task<CommerceCommand>>)); arg.AddCompletexType(typeof(ConcurrentDictionary<string, string>));
-
AddCommerceEntity
: this extension maps a CLR class andall
its derived classes as entities. For example:RequestResponsearg.AddCommerceEntity(typeof(CommerceEntity)); arg.AddCommerceEntity(typeof(Component));