Consider a Headers
entity set with contained entity sets Headers(...)/Items
and Headers(...)/Items(...)/Subitems
. Each entity type has a server-generated uuid
and a canUpdate
property. The header has an additional canInsertItems
and the item has canInsertSubitems
which govern insertability. Insertability of headers depends on the permissions contained in a Permissions
singleton. The header also has a canUpdateSubsetOfItems
which governs updatability with /$filter(...)/$each
(the analogous thing on item level is omitted from this example).
The following annotations express insertability and updatability in terms of these properties. Deletability is analogous to updatability but omitted from this example.
For the header level, the entity set is annotated directly.
"self.Container/Headers": {
"@Capabilities.InsertRestrictions": {
"Insertable": {"$Path": "/self.Container/Permissions/canInsertHeaders"},
"NonInsertableProperties": ["uuid"]
},
"@Capabilities.UpdateRestrictions": {
"Updatable": {"$Path": "canUpdate"},
"NonUpdatableProperties": ["uuid"]
}
}
The item level has no named entity set. It is annotated using NavigationRestrictions
on header level and InsertRestrictions
and UpdateRestrictions
on item level. When a property could be expressed either on the deeper item level or on the higher-up header level, the deeper level is generally preferred: For example, the NonUpdatableProperties
property in the deeper UpdateRestrictions
is favored over its commented-out namesake in the higher-up NavigationRestrictions
, and the commented-out Updatable
is even invalid, because the instance path to canUpdate
is collection-valued. But the higher-up InsertRestrictions/Insertable
and UpdateRestrictions/FilterSegmentSupported
cannot be avoided, because the instance paths to canInsertItems
and canUpdateSubsetOfItems
must be evaluated on header level.
"self.Container/Headers": {
"@Capabilities.NavigationRestrictions": {
"RestrictedProperties": [{
"NavigationProperty": "Items",
"InsertRestrictions": {
// DISCOURAGED: "NonInsertableProperties": ["Items/uuid"],
"Insertable": {"$Path": "canInsertItems"}
},
"UpdateRestrictions": {
// INVALID: "Updatable": {"$Path": "Items/canUpdate"},
// DISCOURAGED: "NonUpdatableProperties": ["Items/uuid"],
"FilterSegmentSupported": {"$Path": "canUpdateSubsetOfItems"}
}
}]
}
},
"self.Container/Headers/Items": {
"@Capabilities.InsertRestrictions": {
"NonInsertableProperties": ["uuid"]
},
"@Capabilities.UpdateRestrictions": {
"Updatable": {"$Path": "canUpdate"},
"NonUpdatableProperties": ["uuid"]
}
}
However, if insertability was static, the value would be a boolean literal and no path expressions would be required. In that case the deeper InsertRestrictions/Insertable
term would be favored over the higher-up one.
"self.Container/Headers/Items": {
"@Capabilities.InsertRestrictions": {
"Insertable": true,
"NonInsertableProperties": ["uuid"]
}
}
The subitem level is annotated using NavigationRestrictions
on item level and InsertRestrictions
and UpdateRestrictions
on subitem level.
"self.Container/Headers/Items": {
"@Capabilities.NavigationRestrictions": {
"RestrictedProperties": [{
"NavigationProperty": "Subitems",
"InsertRestrictions": {
"Insertable": {"$Path": "canInsertSubitems"}
}
}]
}
},
"self.Container/Headers/Items/Subitems": {
"@Capabilities.InsertRestrictions": {
"NonInsertableProperties": ["uuid"]
},
"@Capabilities.UpdateRestrictions": {
"Updatable": {"$Path": "canUpdate"},
"NonUpdatableProperties": ["uuid"]
}
}