From 6e49337e9f1927163c19060cb5985fb08b2379f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= The apply expression enables a value to be obtained by applying a client-side function. The apply expression MAY have operand expressions. The operand expressions are used as parameters to the client-side function. Apply expressions are represented as an object with a member It MAY contain annotations. The cast expression casts the value obtained from its single child expression to the specified type. The cast expression follows the same rules as the Cast expressions are represented as an object with a member It MAY contain annotations. If the specified type is a primitive type or a collection of primitive types, the facet members The second and third child expressions are evaluated conditionally. The result MUST be type compatible with the type expected by the surrounding expression. If the first expression evaluates to Conditional expressions are represented as an object with a member It MAY contain annotations. The Is-of expressions are represented as an object with a member It MAY contain annotations. If the specified type is a primitive type or a collection of primitive types, the facet members A labeled element expression MUST contain exactly one child expression. The value of the child expression is also the value of the labeled element expression. A labeled element expression MUST provide a simple identifier value as its name that MUST be unique within the schema containing the expression. Labeled element expressions are represented as an object with a member It MAY contain annotations. The labeled element reference expression MUST specify the qualified name of a labeled element expression in scope and returns the value of the identified labeled element expression as its value. Labeled element reference expressions are represented as an object with a member Null expression containing annotations are represented as an object with a member The URL reference expression MUST contain exactly one expression of type The response body of the URL reference expressions are represented as an object with a single member It MAY contain annotations. Example 87: this annotation “morphs” the entity type from example 13 into a structured type with two structural properties The URL reference expression enables a value to be obtained by sending a Example 87: this annotation “morphs” the entity type from example 13 into a structured type with two structural properties The URL reference expression enables a value to be obtained by sending a
14.4.4 Apply Client-Side Functions
+$Apply
$Apply
and $Function
$Apply
whose value is an array of annotation expressions, and a member $Function
whose value is a string containing the qualified name of the client-side function to be applied.14.4.5 Cast
cast
canonical function defined in OData-URL.
+$Cast
$Cast
$Cast
whose value is an annotation expression, a member $Type
whose value is a string containing the qualified type name, and optionally a member $Collection
with a value of true
.$MaxLength
, $Unicode
, $Precision
, $Scale
, and $SRID
MAY be specified if applicable to the specified primitive type. If the facet members are not specified, their values are considered unspecified.14.4.7 If-The
true
, the second expression MUST be evaluated and its value MUST be returned as the result of the if-then-else expression. If the first expression evaluates to false
and a third child element is present, it MUST be evaluated and its value MUST be returned as the result of the if-then-else expression. If no third expression is present, nothing is added to the surrounding collection.
+$If
$If
$If
whose value is an array of two or three annotation expressions.
$If
14.4.8 Is-Of
is-of
expression checks whether the value obtained from its single child expression is compatible with the specified type. It returns true
if the child expression returns a type that is compatible with the specified type, and false
otherwise.
+$IsOf
$IsOf
$IsOf
whose value is an annotation expression, a member $Type
whose value is a string containing an qualified type name, and optionally a member $Collection
with a value of true
.$MaxLength
, $Unicode
, $Precision
, $Scale
, and $SRID
MAY be specified if applicable to the specified primitive type. If the facet members are not specified, their values are considered unspecified.14
+$LabeledElement
$LabeledElement
$LabeledElement
whose value is an annotation expression, and a member $Name
whose value is a string containing the labeled element’s name.
$LabeledEle
14.4.10 Labeled Element Reference
+$LabeledElementReference
$LabeledElementReference
$LabeledElementReference
whose value is a string containing an qualified name.14.4.11 Null
"@UI.DisplayName": null,
+$Null
$Null
$Null
whose value is the literal null
.14.4.13
Edm.String
. Its value is treated as a URL that MAY be relative or absolute; relative URLs are relative to the URL of the document containing the URL reference expression, or relative to a base URL specified in a format-specific way.GET
request MUST be returned as the result of the URL reference expression. The result of the URL reference expression MUST be type compatible with the type expected by the surrounding expression.
+$UrlRef
$UrlRef
$UrlRef
whose value is an annotation expression.$DivBy
$Mod
$Apply
$Cast
$If
$IsOf
$LabeledElement
$LabeledElementReference
$Null
$UrlRef
$Function
$Cast
$If
$IsOf
$LabeledElement
$LabeledElementReference
$Null
$UrlRef
14.4.12 Record
GivenName
and Surname
and two navigation properties DirectSupervisor
and CostCenter
. The first three properties simply rename properties of the annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service"@person.Employee": {
-"@type": "https://example.org/vocabs/person#org.example.person.Manager",
- "@Core.Description": "Annotation on record",
- "GivenName": {
- "$Path": "FirstName"
- },
- "GivenName@Core.Description": "Annotation on record member",
- "Surname": {
- "$Path": "LastName"
- },
- "DirectSupervisor": {
- "$Path": "Manager"
- },
- "CostCenter": {
- "$UrlRef": {
- "$Apply": [
- "http://host/anotherservice/CostCenters('{ccid}')",
- {
- "$LabeledElement": {
- "$Path": "CostCenterID"
- },
- "$Name": "ccid"
- }
- ],
- "$Function": "odata.fillUriTemplate"
- }
- }
- }
"$Annotations": {
+"org.example.Person": {
+ "@org.example.hcm.Employee": {
+ "@type": "https://example.org/vocabs/person#org.example.person.Manager",
+ "@Core.Description": "Annotation on record",
+ "GivenName": {
+ "$Path": "FirstName"
+ },
+ "GivenName@Core.Description": "Annotation on record member",
+ "Surname": {
+ "$Path": "LastName"
+ },
+ "DirectSupervisor": {
+ "$Path": "Manager"
+ },
+ "CostCenter": {
+ "$UrlRef": {
+ "$Apply": [
+ "http://host/anotherservice/CostCenters('{ccid}')",
+ {
+ "$LabeledElement": {
+ "$Path": "CostCenterID"
+ },
+ "$Name": "ccid"
+ }
+ ],
+ "$Function": "odata.fillUriTemplate"
+ }
+ }
+ }
+ }
+ }
14.4.13 URL Reference
GET
request.
GivenName
and Surname
and two navigation properties DirectSupervisor
and CostCenter
. The first three properties simply rename properties of the annotated entity type, the fourth adds a calculated navigation property that is pointing to a different serviceAnnotation Term="org.example.person.Employee">
- <Record>
- <Annotation Term="Core.Description" String="Annotation on record" />
- <PropertyValue Property="GivenName" Path="FirstName">
- <Annotation Term="Core.Description"
- < String="Annotation on record member" />
-PropertyValue>
- </PropertyValue Property="Surname" Path="LastName" />
- <PropertyValue Property="DirectSupervisor" Path="Manager" />
- <PropertyValue Property="CostCenter">
- <UrlRef>
- <Apply Function="odata.fillUriTemplate">
- <String>http://host/anotherservice/CostCenters('{ccid}')</String>
- <LabeledElement Name="ccid" Path="CostCenterID" />
- <Apply>
- </UrlRef>
- </PropertyValue>
- </Record>
- </Annotation> </
Annotations Target="org.example.Person">
+ <Annotation Term="org.example.hcm.Employee">
+ <Record Type="org.example.hcm.Manager">
+ <Annotation Term="Core.Description" String="Annotation on record" />
+ <PropertyValue Property="GivenName" Path="FirstName">
+ <Annotation Term="Core.Description"
+ < String="Annotation on record member" />
+PropertyValue>
+ </PropertyValue Property="Surname" Path="LastName" />
+ <PropertyValue Property="DirectSupervisor" Path="Manager" />
+ <PropertyValue Property="CostCenter">
+ <UrlRef>
+ <Apply Function="odata.fillUriTemplate">
+ <String>http://host/anotherservice/CostCenters('{ccid}')</String>
+ <LabeledElement Name="ccid" Path="CostCenterID" />
+ <Apply>
+ </UrlRef>
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ </Annotations> </
14.4.13 URL Reference
GET
request..
The OData-ABNF searchExpr
syntax rule defines the formal grammar of the search expression.
$format
The $format
system query option allows clients to request a response in a particular format and is useful for clients without access to request headers for standard content-type negotiation. Where present $format
takes precedence over standard content-type negotiation.
The annotation identifier odata
is reserved for future extensions of the protocol and format. Instance annotations MUST have a namespace or alias that is different from odata
.
Annotations can be applied to any name/value pair in a JSON payload that represents a value of any type from the entity data model. Clients should never error due to an unexpected annotation in a JSON payload.
-Annotations are always expressed as name/value pairs. For entity data model constructs represented as JSON objects the annotation name/value pairs are placed within the object; for constructs represented as JSON arrays or primitives they are placed next to the annotated model construct. When annotating a payload that represents a single primitive or collection value, the annotations for the value appear next to the value
property and are not prefixed with a property name.
Annotations are always expressed as name/value pairs. For entity data model constructs represented as JSON objects the annotation name/value pairs are placed within the object; for constructs represented as JSON arrays or primitives, including null, they are placed next to the annotated model construct and have the name of the annotated property before the @
. An annotation in the latter format can also take the place of an absent property. When annotating a payload that represents a single primitive or collection value, the annotations for the value appear next to the value
property and are not prefixed with a property name.
Example 54:
{
diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md
index 8a2f8a204..b5eb8eb96 100644
--- a/docs/odata-json-format/odata-json-format.md
+++ b/docs/odata-json-format/odata-json-format.md
@@ -3390,8 +3390,10 @@ should never error due to an unexpected annotation in a JSON payload.
Annotations are always expressed as name/value pairs. For entity data
model constructs represented as JSON objects the annotation name/value
pairs are placed within the object; for constructs represented as JSON
-arrays or primitives they are placed next to the annotated model
-construct. When annotating a payload that represents a
+arrays or primitives, including null, they are placed next to the annotated model
+construct and have the name of the annotated property before the `@`.
+An annotation in the latter format can also take the place of an absent property.
+When annotating a payload that represents a
[single primitive or collection value](#IndividualPropertyorOperationResponse),
the annotations for the value appear next to the `value`
property and are not prefixed with a property name.
diff --git a/odata-json-format/20 Instance Annotations.md b/odata-json-format/20 Instance Annotations.md
index c80504512..0601e8a6f 100644
--- a/odata-json-format/20 Instance Annotations.md
+++ b/odata-json-format/20 Instance Annotations.md
@@ -26,8 +26,10 @@ should never error due to an unexpected annotation in a JSON payload.
Annotations are always expressed as name/value pairs. For entity data
model constructs represented as JSON objects the annotation name/value
pairs are placed within the object; for constructs represented as JSON
-arrays or primitives they are placed next to the annotated model
-construct. When annotating a payload that represents a
+arrays or primitives, including null, they are placed next to the annotated model
+construct and have the name of the annotated property before the `@`.
+An annotation in the latter format can also take the place of an absent property.
+When annotating a payload that represents a
[single primitive or collection value](#IndividualPropertyorOperationResponse),
the annotations for the value appear next to the `value`
property and are not prefixed with a property name.
From af6ad7d404d8516d194b4545a96f4366b93c550f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Wed, 29 Nov 2023 17:35:22 +0100
Subject: [PATCH 05/22] ODATA-1517 (#60)
Co-authored-by: Ralf Handl
---
docs/odata-csdl-json/odata-csdl-json.html | 1303 ++++++++++----------
docs/odata-csdl-json/odata-csdl-json.md | 9 +-
docs/odata-csdl-xml/odata-csdl-xml.html | 809 ++++++------
docs/odata-csdl-xml/odata-csdl-xml.md | 9 +-
odata-csdl/14 Vocabulary and Annotation.md | 9 +-
5 files changed, 1078 insertions(+), 1061 deletions(-)
diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html
index 38ced93c3..516403bc1 100644
--- a/docs/odata-csdl-json/odata-csdl-json.html
+++ b/docs/odata-csdl-json/odata-csdl-json.html
@@ -2555,8 +2555,9 @@ 14.4.1.1 Path
A model path MAY contain path segments starting with a navigation property, then followed by an at (@
) character, then followed by the qualified name of a term in scope, and optionally followed by a hash (#
) character and a simple identifier which is interpreted as a qualifier for the term. If the navigation property has not been annotated with that term (and if present, with that qualifier), the path segment evaluates to the null value. This allows addressing annotations on the navigation property itself; annotations on the entity type specified by the navigation property are addressed via a term-cast segment.
Example 64: model path addressing an annotation on a navigation property
-.../Items@Capabilities.InsertRestrictions/Insertable
+Example 64: model path segment addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property
+.../Items@Core.Description
+.../Items/@Core.Description
An instance path MAY contain path segments starting with an entity set or a collection-valued navigation property, then followed by a key predicate using parentheses-style convention, see OData-URL. The key values are either primitive literals or instance paths. If the key value is a relative instance path, it is interpreted according to the same rule below as the instance path it is part of, not relative to the instance identified by the preceding path part.
Example 68:
-"@UI.ReferenceFacet": "Product/Supplier/@UI.LineItem",
-"@UI.CollectionFacet#Contacts": [
-"Supplier/@Communication.Contact",
- "Customer/@Communication.Contact"
- ]
"@UI.ReferenceFacet": "Product/Supplier/@UI.LineItem",
+"@UI.CollectionFacet#Contacts": [
+"Supplier/@Communication.Contact",
+ "Customer/@Communication.Contact"
+ ]
The model element path expression provides a value for terms or term properties that specify the built-in type Edm.ModelElementPath
. Its argument is a model path.
Example 69:
-"@org.example.MyFavoriteModelElement": "/self.someAction"
"@org.example.MyFavoriteModelElement": "/self.someAction"
The navigation property path expression provides a value for terms or term properties that specify the built-in types Edm.NavigationPropertyPath
, Edm.AnyPropertyPath
, or Edm.ModelElementPath
. Its argument is a model path with the following restriction:
Example 70:
-"@UI.HyperLink": "Supplier",
-
-"@Capabilities.UpdateRestrictions": {
-"NonUpdatableNavigationProperties": [
- "Supplier",
- "Category"
- ]
- }
"@UI.HyperLink": "Supplier",
+
+"@Capabilities.UpdateRestrictions": {
+"NonUpdatableNavigationProperties": [
+ "Supplier",
+ "Category"
+ ]
+ }
The property path expression provides a value for terms or term properties that specify one of the built-in types Edm.PropertyPath
, Edm.AnyPropertyPath
, or Edm.ModelElementPath
. Its argument is a model path with the following restriction:
Example 71:
-"@UI.RefreshOnChangeOf": "ChangedAt",
-
-"@Capabilities.UpdateRestrictions": {
-"NonUpdatableProperties": [
- "CreatedAt",
- "ChangedAt"
- ]
- }
"@UI.RefreshOnChangeOf": "ChangedAt",
+
+"@Capabilities.UpdateRestrictions": {
+"NonUpdatableProperties": [
+ "CreatedAt",
+ "ChangedAt"
+ ]
+ }
The value path expression allows assigning a value by traversing an object graph. It can be used in annotations that target entity containers, entity sets, entity types, complex types, navigation properties of structured types, and structural properties of structured types. Its argument is an instance path.
@@ -2725,13 +2726,13 @@$Path
Example 72:
-"@UI.DisplayName": {
-"$Path": "FirstName"
- },
-
-"@UI.DisplayName#second": {
-"$Path": "@vCard.Address#work/FullName"
- }
"@UI.DisplayName": {
+"$Path": "FirstName"
+ },
+
+"@UI.DisplayName#second": {
+"$Path": "@vCard.Address#work/FullName"
+ }
Annotations MAY use the following logical and comparison expressions which evaluate to a Boolean value. These expressions MAY be combined and they MAY be used anywhere instead of a Boolean expression.
@@ -2767,98 +2768,98 @@Example 73:
-{
-"$And": [
- {
- "$Path": "IsMale"
- },
- {
- "$Path": "IsMarried"
- }
- ]
- },
-{
-"$Or": [
- {
- "$Path": "IsMale"
- },
- {
- "$Path": "IsMarried"
- }
- ]
- },
-{
-"$Not": {
- "$Path": "IsMale"
- }
- },
-{
-"$Eq": [
- null,
- {
- "$Path": "IsMale"
- }
- ]
- },
-{
-"$Ne": [
- null,
- {
- "$Path": "IsMale"
- }
- ]
- },
-{
-"$Gt": [
- {
- "$Path": "Price"
- },
- 20
- ]
- },
-{
-"$Ge": [
- {
- "$Path": "Price"
- },
- 10
- ]
- },
-{
-"$Lt": [
- {
- "$Path": "Price"
- },
- 20
- ]
- },
-{
-"$Le": [
- {
- "$Path": "Price"
- },
- 100
- ]
- },
-{
-"$Has": [
- {
- "$Path": "Fabric"
- },
- "Red"
- ]
- },
-{
-"$In": [
- {
- "$Path": "Size"
- },
- [
- "XS",
- "S"
- ]
- ]
- }
{
+"$And": [
+ {
+ "$Path": "IsMale"
+ },
+ {
+ "$Path": "IsMarried"
+ }
+ ]
+ },
+{
+"$Or": [
+ {
+ "$Path": "IsMale"
+ },
+ {
+ "$Path": "IsMarried"
+ }
+ ]
+ },
+{
+"$Not": {
+ "$Path": "IsMale"
+ }
+ },
+{
+"$Eq": [
+ null,
+ {
+ "$Path": "IsMale"
+ }
+ ]
+ },
+{
+"$Ne": [
+ null,
+ {
+ "$Path": "IsMale"
+ }
+ ]
+ },
+{
+"$Gt": [
+ {
+ "$Path": "Price"
+ },
+ 20
+ ]
+ },
+{
+"$Ge": [
+ {
+ "$Path": "Price"
+ },
+ 10
+ ]
+ },
+{
+"$Lt": [
+ {
+ "$Path": "Price"
+ },
+ 20
+ ]
+ },
+{
+"$Le": [
+ {
+ "$Path": "Price"
+ },
+ 100
+ ]
+ },
+{
+"$Has": [
+ {
+ "$Path": "Fabric"
+ },
+ "Red"
+ ]
+ },
+{
+"$In": [
+ {
+ "$Path": "Size"
+ },
+ [
+ "XS",
+ "S"
+ ]
+ ]
+ }
Annotations MAY use the following arithmetic expressions which evaluate to a numeric value. These expressions MAY be combined, and they MAY be used anywhere instead of a numeric expression of the appropriate type. The semantics and evaluation rules for each arithmetic expression is identical to the corresponding arithmetic operator defined in OData-URL.
@@ -2911,71 +2912,71 @@Example 74:
-{
-"$Add": [
- {
- "$Path": "StartDate"
- },
- {
- "$Path": "Duration"
- }
- ]
- },
-{
-"$Sub": [
- {
- "$Path": "Revenue"
- },
- {
- "$Path": "Cost"
- }
- ]
- },
-{
-"$Neg": {
- "$Path": "Height"
- }
- },
-{
-"$Mul": [
- {
- "$Path": "NetPrice"
- },
- {
- "$Path": "TaxRate"
- }
- ]
- },
-{
-"$Div": [
- {
- "$Path": "Quantity"
- },
- {
- "$Path": "QuantityPerParcel"
- }
- ]
- },
-{
-"$DivBy": [
- {
- "$Path": "Quantity"
- },
- {
- "$Path": "QuantityPerParcel"
- }
- ]
- },
-{
-"$Mod": [
- {
- "$Path": "Quantity"
- },
- {
- "$Path": "QuantityPerParcel"
- }
- ]
- }
{
+"$Add": [
+ {
+ "$Path": "StartDate"
+ },
+ {
+ "$Path": "Duration"
+ }
+ ]
+ },
+{
+"$Sub": [
+ {
+ "$Path": "Revenue"
+ },
+ {
+ "$Path": "Cost"
+ }
+ ]
+ },
+{
+"$Neg": {
+ "$Path": "Height"
+ }
+ },
+{
+"$Mul": [
+ {
+ "$Path": "NetPrice"
+ },
+ {
+ "$Path": "TaxRate"
+ }
+ ]
+ },
+{
+"$Div": [
+ {
+ "$Path": "Quantity"
+ },
+ {
+ "$Path": "QuantityPerParcel"
+ }
+ ]
+ },
+{
+"$DivBy": [
+ {
+ "$Path": "Quantity"
+ },
+ {
+ "$Path": "QuantityPerParcel"
+ }
+ ]
+ },
+{
+"$Mod": [
+ {
+ "$Path": "Quantity"
+ },
+ {
+ "$Path": "QuantityPerParcel"
+ }
+ ]
+ }
The apply expression enables a value to be obtained by applying a client-side function. The apply expression MAY have operand expressions. The operand expressions are used as parameters to the client-side function.
@@ -2990,24 +2991,24 @@Edm.Binary
as binaryValue
, Edm.Boolean
as booleanValue
etc.
Example 75:
-"@UI.DisplayName": {
-"$Apply": [
- "Product: ",
- {
- "$Path": "ProductName"
- },
- " (",
- {
- "$Path": "Available/Quantity"
- },
- " ",
- {
- "$Path": "Available/Unit"
- },
- " available)"
- ],
- "$Function": "odata.concat"
- }
"@UI.DisplayName": {
+"$Apply": [
+ "Product: ",
+ {
+ "$Path": "ProductName"
+ },
+ " (",
+ {
+ "$Path": "Available/Quantity"
+ },
+ " ",
+ {
+ "$Path": "Available/Unit"
+ },
+ " available)"
+ ],
+ "$Function": "odata.concat"
+ }
ProductName
is of type String
, Quantity
in complex type Available
is of type Decimal
, and Unit
in Available
is of type enumeration, so the result of the Path
expression is represented as the member name of the enumeration value.
odata.fillUriTemplate
Example 76: assuming there are no special characters in values of the Name property of the Actor entity
-{
-"$Apply": [
- "http://host/someAPI/Actors/{actorName}/CV",
- {
- "$LabeledElement": {
- "$Path": "Actor/Name"
- },
- "$Name": "self.actorName"
- }
- ],
- "$Function": "odata.fillUriTemplate"
- }
{
+"$Apply": [
+ "http://host/someAPI/Actors/{actorName}/CV",
+ {
+ "$LabeledElement": {
+ "$Path": "Actor/Name"
+ },
+ "$Name": "self.actorName"
+ }
+ ],
+ "$Function": "odata.fillUriTemplate"
+ }
odata.matchesPattern
The odata.matchesPattern
client-side function takes two string expressions as arguments and returns a Boolean value. It is the counterpart of the identically named URL function OData-URL, section 5.1.1.7.1.
The function returns true if the second expression evaluates to an ECMAScript (JavaScript) regular expression and the result of the first argument expression matches that regular expression, using syntax and semantics of ECMAScript regular expressions.
Example 77: all non-empty FirstName
values not containing the letters b
, c
, or d
evaluate to true
{
-"$Apply": [
- {
- "$Path": "FirstName"
- },
- "^[^b-d]+$"
- ],
- "$Function": "odata.matchesPattern"
- }
{
+"$Apply": [
+ {
+ "$Path": "FirstName"
+ },
+ "^[^b-d]+$"
+ ],
+ "$Function": "odata.matchesPattern"
+ }
odata.uriEncode
The odata.uriEncode
client-side function takes one argument of primitive type and returns the URL-encoded OData literal that can be used as a key value in OData URLs or in the query part of OData URLs.
Note: string literals are surrounded by single quotes as required by the paren-style key syntax.
Example 78:
-{
-"$Apply": [
- "http://host/service/Genres({genreName})",
- {
- "$LabeledElement": {
- "$Apply": [
- {
- "$Path": "NameOfMovieGenre"
- }
- ],
- "$Function": "odata.uriEncode"
- },
- "$Name": "self.genreName"
- }
- ],
- "$Function": "odata.fillUriTemplate"
- }
{
+"$Apply": [
+ "http://host/service/Genres({genreName})",
+ {
+ "$LabeledElement": {
+ "$Apply": [
+ {
+ "$Path": "NameOfMovieGenre"
+ }
+ ],
+ "$Function": "odata.uriEncode"
+ },
+ "$Name": "self.genreName"
+ }
+ ],
+ "$Function": "odata.fillUriTemplate"
+ }
The cast expression casts the value obtained from its single child expression to the specified type. The cast expression follows the same rules as the cast
canonical function defined in OData-URL.
$Cast
Example 79:
-"@UI.Threshold": {
-"$Cast": {
- "$Path": "Average"
- },
- "$Type": "Edm.Decimal"
- }
"@UI.Threshold": {
+"$Cast": {
+ "$Path": "Average"
+ },
+ "$Type": "Edm.Decimal"
+ }
The collection expression enables a value to be obtained from zero or more item expressions. The value calculated by the collection expression is the collection of the values calculated by each of the item expressions. The values of the child expressions MUST all be type compatible.
@@ -3094,11 +3095,11 @@Example 80:
-"@seo.SeoTerms": [
-"Product",
- "Supplier",
- "Customer"
- ]
"@seo.SeoTerms": [
+"Product",
+ "Supplier",
+ "Customer"
+ ]
The if-then-else expression enables a value to be obtained by evaluating a condition expression. It MUST contain exactly three child expressions. There is one exception to this rule: if and only if the if-then-else expression is an item of a collection expression, the third child expression MAY be omitted, reducing it to an if-then expression. This can be used to conditionally add an element to a collection.
@@ -3112,15 +3113,15 @@$If
Example 81: the condition is a value path expression referencing the Boolean property IsFemale
, whose value then determines the value of the $If
expression (or so it was long ago)
"@person.Gender": {
-"$If": [
- {
- "$Path": "IsFemale"
- },
- "Female",
- "Male"
- ]
- }
"@person.Gender": {
+"$If": [
+ {
+ "$Path": "IsFemale"
+ },
+ "Female",
+ "Male"
+ ]
+ }
The is-of
expression checks whether the value obtained from its single child expression is compatible with the specified type. It returns true
if the child expression returns a type that is compatible with the specified type, and false
otherwise.
$IsOf
Example 82:
-"@Self.IsPreferredCustomer": {
-"$IsOf": {
- "$Path": "Customer"
- },
- "$Type": "self.PreferredCustomer"
- }
"@Self.IsPreferredCustomer": {
+"$IsOf": {
+ "$Path": "Customer"
+ },
+ "$Type": "self.PreferredCustomer"
+ }
The labeled element expression assigns a name to its single child expression. The value of the child expression can then be reused elsewhere with a labeled element reference expression.
@@ -3150,12 +3151,12 @@$LabeledEle
Example 83:
-"@UI.DisplayName": {
-"$LabeledElement": {
- "$Path": "FirstName"
- },
- "$Name": "CustomerFirstName"
- }
+"@UI.DisplayName": {
+"$LabeledElement": {
+ "$Path": "FirstName"
+ },
+ "$Name": "CustomerFirstName"
+ }
14.4.10 Labeled Element Reference
The labeled element reference expression MUST specify the qualified name of a labeled element expression in scope and returns the value of the identified labeled element expression as its value.
@@ -3165,9 +3166,9 @@
Example 84:
-"@UI.DisplayName": {
-"$LabeledElementReference": "self.CustomerFirstName"
- }
+"@UI.DisplayName": {
+"$LabeledElementReference": "self.CustomerFirstName"
+ }
14.4.11 Null
The null expression indicates the absence of a value. The null expression MAY be annotated.
@@ -3176,7 +3177,7 @@ 14.4.11 Null
Example 85:
-"@UI.DisplayName": null,
+"@UI.DisplayName": null,
$Null
@@ -3184,10 +3185,10 @@ $Null
Example 86:
-"@UI.Address": {
-"$Null": null,
- "@self.Reason": "Private"
- }
+"@UI.Address": {
+"$Null": null,
+ "@self.Reason": "Private"
+ }
14.4.12 Record
The record expression enables a new entity type or complex type instance to be constructed.
@@ -3201,38 +3202,38 @@ 14.4.12 Record
Example 87: this annotation “morphs” the entity type from example 13 into a structured type with two structural properties GivenName
and Surname
and two navigation properties DirectSupervisor
and CostCenter
. The first three properties simply rename properties of the annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service
-"$Annotations": {
-"org.example.Person": {
- "@org.example.hcm.Employee": {
- "@type": "https://example.org/vocabs/person#org.example.person.Manager",
- "@Core.Description": "Annotation on record",
- "GivenName": {
- "$Path": "FirstName"
- },
- "GivenName@Core.Description": "Annotation on record member",
- "Surname": {
- "$Path": "LastName"
- },
- "DirectSupervisor": {
- "$Path": "Manager"
- },
- "CostCenter": {
- "$UrlRef": {
- "$Apply": [
- "http://host/anotherservice/CostCenters('{ccid}')",
- {
- "$LabeledElement": {
- "$Path": "CostCenterID"
- },
- "$Name": "ccid"
- }
- ],
- "$Function": "odata.fillUriTemplate"
- }
- }
- }
- }
- }
+"$Annotations": {
+"org.example.Person": {
+ "@org.example.hcm.Employee": {
+ "@type": "https://example.org/vocabs/person#org.example.person.Manager",
+ "@Core.Description": "Annotation on record",
+ "GivenName": {
+ "$Path": "FirstName"
+ },
+ "GivenName@Core.Description": "Annotation on record member",
+ "Surname": {
+ "$Path": "LastName"
+ },
+ "DirectSupervisor": {
+ "$Path": "Manager"
+ },
+ "CostCenter": {
+ "$UrlRef": {
+ "$Apply": [
+ "http://host/anotherservice/CostCenters('{ccid}')",
+ {
+ "$LabeledElement": {
+ "$Path": "CostCenterID"
+ },
+ "$Name": "ccid"
+ }
+ ],
+ "$Function": "odata.fillUriTemplate"
+ }
+ }
+ }
+ }
+ }
14.4.13 URL Reference
The URL reference expression enables a value to be obtained by sending a GET
request.
@@ -3245,29 +3246,29 @@ $UrlRef
Example 88:
-"@org.example.person.Supplier": {
-"$UrlRef": {
- "$Apply": [
- "http://host/service/Suppliers({suppID})",
- {
- "$LabeledElement": {
- "$Apply": [
- {
- "$Path": "SupplierId"
- }
- ],
- "$Function": "odata.uriEncode"
- },
- "$Name": "suppID"
- }
- ],
- "$Function": "odata.fillUriTemplate"
- }
- },
-
- "@Core.LongDescription#element": {
-"$UrlRef": "http://host/wiki/HowToUse"
- }
+"@org.example.person.Supplier": {
+"$UrlRef": {
+ "$Apply": [
+ "http://host/service/Suppliers({suppID})",
+ {
+ "$LabeledElement": {
+ "$Apply": [
+ {
+ "$Path": "SupplierId"
+ }
+ ],
+ "$Function": "odata.uriEncode"
+ },
+ "$Name": "suppID"
+ }
+ ],
+ "$Function": "odata.fillUriTemplate"
+ }
+ },
+
+ "@Core.LongDescription#element": {
+"$UrlRef": "http://host/wiki/HowToUse"
+ }
15 Identifier and Path Values
@@ -3305,270 +3306,270 @@ 16 CSDL Ex
16.1 Products and Categories Example
Example 90:
-{
-"$Version": "4.0",
- "$EntityContainer": "ODataDemo.DemoService",
- "$Reference": {
- "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
- "$Include": [
- {
- "$Namespace": "Org.OData.Core.V1",
- "$Alias": "Core",
- "@Core.DefaultNamespace": true
- }
- ]
- },
- "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json": {
- "$Include": [
- {
- "$Namespace": "Org.OData.Measures.V1",
- "$Alias": "Measures"
- }
- ]
- }
- },
- "ODataDemo": {
- "$Alias": "self",
- "@Core.DefaultNamespace": true,
- "Product": {
- "$Kind": "EntityType",
- "$Key": [
- "ID"
- ],
- "ID": {},
- "Description": {
- "$Nullable": true,
- "@Core.IsLanguageDependent": true
- },
- "ReleaseDate": {
- "$Nullable": true,
- "$Type": "Edm.Date"
- },
- "DiscontinuedDate": {
- "$Nullable": true,
- "$Type": "Edm.Date"
- },
- "Rating": {
- "$Nullable": true,
- "$Type": "Edm.Int32"
- },
- "Price": {
- "$Nullable": true,
- "$Type": "Edm.Decimal",
- "@Measures.ISOCurrency": {
- "$Path": "Currency"
- }
- },
- "Currency": {
- "$Nullable": true,
- "$MaxLength": 3
- },
- "Category": {
- "$Kind": "NavigationProperty",
- "$Type": "self.Category",
- "$Partner": "Products"
- },
- "Supplier": {
- "$Kind": "NavigationProperty",
- "$Nullable": true,
- "$Type": "self.Supplier",
- "$Partner": "Products"
- }
- },
- "Category": {
- "$Kind": "EntityType",
- "$Key": [
- "ID"
- ],
- "ID": {
- "$Type": "Edm.Int32"
- },
- "Name": {
- "@Core.IsLanguageDependent": true
- },
- "Products": {
- "$Kind": "NavigationProperty",
- "$Partner": "Category",
- "$Collection": true,
- "$Type": "self.Product",
- "$OnDelete": "Cascade"
- }
- },
- "Supplier": {
- "$Kind": "EntityType",
- "$Key": [
- "ID"
- ],
- "ID": {},
- "Name": {
- "$Nullable": true
- },
- "Address": {
- "$Type": "self.Address"
- },
- "Concurrency": {
- "$Type": "Edm.Int32"
- },
- "Products": {
- "$Kind": "NavigationProperty",
- "$Partner": "Supplier",
- "$Collection": true,
- "$Type": "self.Product"
- }
- },
- "Country": {
- "$Kind": "EntityType",
- "$Key": [
- "Code"
- ],
- "Code": {
- "$MaxLength": 2
- },
- "Name": {
- "$Nullable": true
- }
- },
- "Address": {
- "$Kind": "ComplexType",
- "Street": {
- "$Nullable": true
- },
- "City": {
- "$Nullable": true
- },
- "State": {
- "$Nullable": true
- },
- "ZipCode": {
- "$Nullable": true
- },
- "CountryName": {
- "$Nullable": true
- },
- "Country": {
- "$Kind": "NavigationProperty",
- "$Nullable": true,
- "$Type": "self.Country",
- "$ReferentialConstraint": {
- "CountryName": "Name"
- }
- }
- },
- "ProductsByRating": [
- {
- "$Kind": "Function",
- "$Parameter": [
- {
- "$Name": "Rating",
- "$Nullable": true,
- "$Type": "Edm.Int32"
- }
- ],
- "$ReturnType": {
- "$Collection": true,
- "$Type": "self.Product"
- }
- }
- ],
- "DemoService": {
- "$Kind": "EntityContainer",
- "Products": {
- "$Collection": true,
- "$Type": "self.Product",
- "$NavigationPropertyBinding": {
- "Category": "Categories"
- }
- },
- "Categories": {
- "$Collection": true,
- "$Type": "self.Category",
- "$NavigationPropertyBinding": {
- "Products": "Products"
- },
- "@Core.Description": "Product Categories"
- },
- "Suppliers": {
- "$Collection": true,
- "$Type": "self.Supplier",
- "$NavigationPropertyBinding": {
- "Products": "Products",
- "Address/Country": "Countries"
- },
- "@Core.OptimisticConcurrency": [
- "Concurrency"
- ]
- },
- "Countries": {
- "$Collection": true,
- "$Type": "self.Country"
- },
- "MainSupplier": {
- "$Type": "self.Supplier",
- "$NavigationPropertyBinding": {
- "Products": "Products"
- },
- "@Core.Description": "Primary Supplier"
- },
- "ProductsByRating": {
- "$EntitySet": "Products",
- "$Function": "self.ProductsByRating"
- }
- }
- }
- }
+{
+"$Version": "4.0",
+ "$EntityContainer": "ODataDemo.DemoService",
+ "$Reference": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
+ "$Include": [
+ {
+ "$Namespace": "Org.OData.Core.V1",
+ "$Alias": "Core",
+ "@Core.DefaultNamespace": true
+ }
+ ]
+ },
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json": {
+ "$Include": [
+ {
+ "$Namespace": "Org.OData.Measures.V1",
+ "$Alias": "Measures"
+ }
+ ]
+ }
+ },
+ "ODataDemo": {
+ "$Alias": "self",
+ "@Core.DefaultNamespace": true,
+ "Product": {
+ "$Kind": "EntityType",
+ "$Key": [
+ "ID"
+ ],
+ "ID": {},
+ "Description": {
+ "$Nullable": true,
+ "@Core.IsLanguageDependent": true
+ },
+ "ReleaseDate": {
+ "$Nullable": true,
+ "$Type": "Edm.Date"
+ },
+ "DiscontinuedDate": {
+ "$Nullable": true,
+ "$Type": "Edm.Date"
+ },
+ "Rating": {
+ "$Nullable": true,
+ "$Type": "Edm.Int32"
+ },
+ "Price": {
+ "$Nullable": true,
+ "$Type": "Edm.Decimal",
+ "@Measures.ISOCurrency": {
+ "$Path": "Currency"
+ }
+ },
+ "Currency": {
+ "$Nullable": true,
+ "$MaxLength": 3
+ },
+ "Category": {
+ "$Kind": "NavigationProperty",
+ "$Type": "self.Category",
+ "$Partner": "Products"
+ },
+ "Supplier": {
+ "$Kind": "NavigationProperty",
+ "$Nullable": true,
+ "$Type": "self.Supplier",
+ "$Partner": "Products"
+ }
+ },
+ "Category": {
+ "$Kind": "EntityType",
+ "$Key": [
+ "ID"
+ ],
+ "ID": {
+ "$Type": "Edm.Int32"
+ },
+ "Name": {
+ "@Core.IsLanguageDependent": true
+ },
+ "Products": {
+ "$Kind": "NavigationProperty",
+ "$Partner": "Category",
+ "$Collection": true,
+ "$Type": "self.Product",
+ "$OnDelete": "Cascade"
+ }
+ },
+ "Supplier": {
+ "$Kind": "EntityType",
+ "$Key": [
+ "ID"
+ ],
+ "ID": {},
+ "Name": {
+ "$Nullable": true
+ },
+ "Address": {
+ "$Type": "self.Address"
+ },
+ "Concurrency": {
+ "$Type": "Edm.Int32"
+ },
+ "Products": {
+ "$Kind": "NavigationProperty",
+ "$Partner": "Supplier",
+ "$Collection": true,
+ "$Type": "self.Product"
+ }
+ },
+ "Country": {
+ "$Kind": "EntityType",
+ "$Key": [
+ "Code"
+ ],
+ "Code": {
+ "$MaxLength": 2
+ },
+ "Name": {
+ "$Nullable": true
+ }
+ },
+ "Address": {
+ "$Kind": "ComplexType",
+ "Street": {
+ "$Nullable": true
+ },
+ "City": {
+ "$Nullable": true
+ },
+ "State": {
+ "$Nullable": true
+ },
+ "ZipCode": {
+ "$Nullable": true
+ },
+ "CountryName": {
+ "$Nullable": true
+ },
+ "Country": {
+ "$Kind": "NavigationProperty",
+ "$Nullable": true,
+ "$Type": "self.Country",
+ "$ReferentialConstraint": {
+ "CountryName": "Name"
+ }
+ }
+ },
+ "ProductsByRating": [
+ {
+ "$Kind": "Function",
+ "$Parameter": [
+ {
+ "$Name": "Rating",
+ "$Nullable": true,
+ "$Type": "Edm.Int32"
+ }
+ ],
+ "$ReturnType": {
+ "$Collection": true,
+ "$Type": "self.Product"
+ }
+ }
+ ],
+ "DemoService": {
+ "$Kind": "EntityContainer",
+ "Products": {
+ "$Collection": true,
+ "$Type": "self.Product",
+ "$NavigationPropertyBinding": {
+ "Category": "Categories"
+ }
+ },
+ "Categories": {
+ "$Collection": true,
+ "$Type": "self.Category",
+ "$NavigationPropertyBinding": {
+ "Products": "Products"
+ },
+ "@Core.Description": "Product Categories"
+ },
+ "Suppliers": {
+ "$Collection": true,
+ "$Type": "self.Supplier",
+ "$NavigationPropertyBinding": {
+ "Products": "Products",
+ "Address/Country": "Countries"
+ },
+ "@Core.OptimisticConcurrency": [
+ "Concurrency"
+ ]
+ },
+ "Countries": {
+ "$Collection": true,
+ "$Type": "self.Country"
+ },
+ "MainSupplier": {
+ "$Type": "self.Supplier",
+ "$NavigationPropertyBinding": {
+ "Products": "Products"
+ },
+ "@Core.Description": "Primary Supplier"
+ },
+ "ProductsByRating": {
+ "$EntitySet": "Products",
+ "$Function": "self.ProductsByRating"
+ }
+ }
+ }
+ }
16.2 Annotations for Products and Categories Example
Example 91:
-{
-"$Version": "4.01",
- "$Reference": {
- "http://host/service/$metadata": {
- "$Include": [
- {
- "$Namespace": "ODataDemo",
- "$Alias": "target"
- }
- ]
- },
- "http://somewhere/Vocabulary/V1": {
- "$Include": [
- {
- "$Namespace": "Some.Vocabulary.V1",
- "$Alias": "Vocabulary1"
- }
- ]
- }
- },
- "External.Annotations": {
- "$Annotations": {
- "target.Supplier": {
- "@Vocabulary1.EMail": null,
- "@Vocabulary1.AccountID": {
- "$Path": "ID"
- },
- "@Vocabulary1.Title": "Supplier Info",
- "@Vocabulary1.DisplayName": {
- "$Apply": [
- {
- "$Path": "Name"
- },
- " in ",
- {
- "$Path": "Address/CountryName"
- }
- ],
- "$Function": "odata.concat"
- }
- },
- "target.Product": {
- "@Vocabulary1.Tags": [
- "MasterData"
- ]
- }
- }
- }
- }
+{
+"$Version": "4.01",
+ "$Reference": {
+ "http://host/service/$metadata": {
+ "$Include": [
+ {
+ "$Namespace": "ODataDemo",
+ "$Alias": "target"
+ }
+ ]
+ },
+ "http://somewhere/Vocabulary/V1": {
+ "$Include": [
+ {
+ "$Namespace": "Some.Vocabulary.V1",
+ "$Alias": "Vocabulary1"
+ }
+ ]
+ }
+ },
+ "External.Annotations": {
+ "$Annotations": {
+ "target.Supplier": {
+ "@Vocabulary1.EMail": null,
+ "@Vocabulary1.AccountID": {
+ "$Path": "ID"
+ },
+ "@Vocabulary1.Title": "Supplier Info",
+ "@Vocabulary1.DisplayName": {
+ "$Apply": [
+ {
+ "$Path": "Name"
+ },
+ " in ",
+ {
+ "$Path": "Address/CountryName"
+ }
+ ],
+ "$Function": "odata.concat"
+ }
+ },
+ "target.Product": {
+ "@Vocabulary1.Tags": [
+ "MasterData"
+ ]
+ }
+ }
+ }
+ }
17 Conformance
diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md
index 0b4ed90d2..b66d706d2 100644
--- a/docs/odata-csdl-json/odata-csdl-json.md
+++ b/docs/odata-csdl-json/odata-csdl-json.md
@@ -4271,9 +4271,14 @@ type specified by the navigation property are addressed via a [term-cast
segment](#TermCast).
::: example
-Example 64: model path addressing an annotation on a navigation property
+Example 64: model path segment addressing an annotation on a navigation property
+vs. term cast addressing an annotation on the resource addressed by the navigation property
```
-.../Items@Capabilities.InsertRestrictions/Insertable
+.../Items@Core.Description
+```
+
+```
+.../Items/@Core.Description
```
:::
diff --git a/docs/odata-csdl-xml/odata-csdl-xml.html b/docs/odata-csdl-xml/odata-csdl-xml.html
index 7908b1256..bf05facbe 100644
--- a/docs/odata-csdl-xml/odata-csdl-xml.html
+++ b/docs/odata-csdl-xml/odata-csdl-xml.html
@@ -2436,8 +2436,9 @@ 14.4.1.1 Path
A model path MAY contain path segments starting with a navigation property, then followed by an at (@
) character, then followed by the qualified name of a term in scope, and optionally followed by a hash (#
) character and a simple identifier which is interpreted as a qualifier for the term. If the navigation property has not been annotated with that term (and if present, with that qualifier), the path segment evaluates to the null value. This allows addressing annotations on the navigation property itself; annotations on the entity type specified by the navigation property are addressed via a term-cast segment.
-Example 64: model path addressing an annotation on a navigation property
-.../Items@Capabilities.InsertRestrictions/Insertable
+Example 64: model path segment addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property
+.../Items@Core.Description
+.../Items/@Core.Description
An instance path MAY contain path segments starting with an entity set or a collection-valued navigation property, then followed by a key predicate using parentheses-style convention, see OData-URL. The key values are either primitive literals or instance paths. If the key value is a relative instance path, it is interpreted according to the same rule below as the instance path it is part of, not relative to the instance identified by the preceding path part.
14.4.1.3 Annotation Path
@@ -2522,15 +2523,15 @@
Example 68:
-Annotation Term="UI.ReferenceFacet"
- < AnnotationPath="Product/Supplier/@UI.LineItem" />
-
-Annotation Term="UI.CollectionFacet" Qualifier="Contacts">
- <Collection>
- <AnnotationPath>Supplier/@Communication.Contact</AnnotationPath>
- <AnnotationPath>Customer/@Communication.Contact</AnnotationPath>
- <Collection>
- </Annotation> </
+Annotation Term="UI.ReferenceFacet"
+ < AnnotationPath="Product/Supplier/@UI.LineItem" />
+
+Annotation Term="UI.CollectionFacet" Qualifier="Contacts">
+ <Collection>
+ <AnnotationPath>Supplier/@Communication.Contact</AnnotationPath>
+ <AnnotationPath>Customer/@Communication.Contact</AnnotationPath>
+ <Collection>
+ </Annotation> </
14.4.1.4 Model Element Path
The model element path expression provides a value for terms or term properties that specify the built-in type Edm.ModelElementPath
. Its argument is a model path.
@@ -2541,12 +2542,12 @@
Example 69:
-Annotation Term="org.example.MyFavoriteModelElement"
- < ModelElementPath="/org.example.someAction" />
-
-Annotation Term="org.example.MyFavoriteModelElement">
- <ModelElementPath>/org.example.someAction</ModelElementPath>
- <Annotation> </
+Annotation Term="org.example.MyFavoriteModelElement"
+ < ModelElementPath="/org.example.someAction" />
+
+Annotation Term="org.example.MyFavoriteModelElement">
+ <ModelElementPath>/org.example.someAction</ModelElementPath>
+ <Annotation> </
14.4.1.5 Navigation Property Path
The navigation property path expression provides a value for terms or term properties that specify the built-in types Edm.NavigationPropertyPath
, Edm.AnyPropertyPath
, or Edm.ModelElementPath
. Its argument is a model path with the following restriction:
@@ -2560,18 +2561,18 @@
Example 70:
-Annotation Term="UI.HyperLink" NavigationPropertyPath="Supplier" />
- <
-Annotation Term="Capabilities.UpdateRestrictions">
- <Record>
- <PropertyValue Property="NonUpdatableNavigationProperties">
- <Collection>
- <NavigationPropertyPath>Supplier</NavigationPropertyPath>
- <NavigationPropertyPath>Category</NavigationPropertyPath>
- <Collection>
- </PropertyValue>
- </Record>
- </Annotation> </
+Annotation Term="UI.HyperLink" NavigationPropertyPath="Supplier" />
+ <
+Annotation Term="Capabilities.UpdateRestrictions">
+ <Record>
+ <PropertyValue Property="NonUpdatableNavigationProperties">
+ <Collection>
+ <NavigationPropertyPath>Supplier</NavigationPropertyPath>
+ <NavigationPropertyPath>Category</NavigationPropertyPath>
+ <Collection>
+ </PropertyValue>
+ </Record>
+ </Annotation> </
14.4.1.6 Property Path
The property path expression provides a value for terms or term properties that specify one of the built-in types Edm.PropertyPath
, Edm.AnyPropertyPath
, or Edm.ModelElementPath
. Its argument is a model path with the following restriction:
@@ -2585,18 +2586,18 @@ E
Example 71:
-Annotation Term="UI.RefreshOnChangeOf" PropertyPath="ChangedAt" />
- <
-Annotation Term="Capabilities.UpdateRestrictions">
- <Record>
- <PropertyValue Property="NonUpdatableProperties">
- <Collection>
- <PropertyPath>CreatedAt</PropertyPath>
- <PropertyPath>ChangedAt</PropertyPath>
- <Collection>
- </PropertyValue>
- </Record>
- </Annotation> </
+Annotation Term="UI.RefreshOnChangeOf" PropertyPath="ChangedAt" />
+ <
+Annotation Term="Capabilities.UpdateRestrictions">
+ <Record>
+ <PropertyValue Property="NonUpdatableProperties">
+ <Collection>
+ <PropertyPath>CreatedAt</PropertyPath>
+ <PropertyPath>ChangedAt</PropertyPath>
+ <Collection>
+ </PropertyValue>
+ </Record>
+ </Annotation> </
14.4.1.7 Value Path
The value path expression allows assigning a value by traversing an object graph. It can be used in annotations that target entity containers, entity sets, entity types, complex types, navigation properties of structured types, and structural properties of structured types. Its argument is an instance path.
@@ -2607,11 +2608,11 @@ Expression
Example 72:
-Annotation Term="org.example.display.DisplayName" Path="FirstName" />
- <
-Annotation Term="org.example.display.DisplayName">
- <Path>@vCard.Address#work/FullName</Path>
- <Annotation> </
+Annotation Term="org.example.display.DisplayName" Path="FirstName" />
+ <
+Annotation Term="org.example.display.DisplayName">
+ <Path>@vCard.Address#work/FullName</Path>
+ <Annotation> </
14.4.2 Comparison and Logical Operators
Annotations MAY use the following logical and comparison expressions which evaluate to a Boolean value. These expressions MAY be combined and they MAY be used anywhere instead of a Boolean expression.
@@ -2647,52 +2648,52 @@
Example 73:
-And>
- <Path>IsMale</Path>
- <Path>IsMarried</Path>
- <And>
- </Or>
- <Path>IsMale</Path>
- <Path>IsMarried</Path>
- <Or>
- </Not>
- <Path>IsMale</Path>
- <Not>
- </Eq>
- <Null />
- <Path>IsMale</Path>
- <Eq>
- </Ne>
- <Null />
- <Path>IsMale</Path>
- <Ne>
- </Gt>
- <Path>Price</Path>
- <Int>20</Int>
- <Gt>
- </Ge>
- <Path>Price</Path>
- <Int>10</Int>
- <Ge>
- </Lt>
- <Path>Price</Path>
- <Int>20</Int>
- <Lt>
- </Le>
- <Path>Price</Path>
- <Int>100</Int>
- <Le>
- </Has>
- <Path>Fabric</Path>
- <EnumMember>org.example.Pattern/Red</EnumMember>
- <Has>
- </In>
- <Path>Size</Path>
- <Collection>
- <String>XS</String>
- <String>S</String>
- <Collection>
- </In> </
+And>
+ <Path>IsMale</Path>
+ <Path>IsMarried</Path>
+ <And>
+ </Or>
+ <Path>IsMale</Path>
+ <Path>IsMarried</Path>
+ <Or>
+ </Not>
+ <Path>IsMale</Path>
+ <Not>
+ </Eq>
+ <Null />
+ <Path>IsMale</Path>
+ <Eq>
+ </Ne>
+ <Null />
+ <Path>IsMale</Path>
+ <Ne>
+ </Gt>
+ <Path>Price</Path>
+ <Int>20</Int>
+ <Gt>
+ </Ge>
+ <Path>Price</Path>
+ <Int>10</Int>
+ <Ge>
+ </Lt>
+ <Path>Price</Path>
+ <Int>20</Int>
+ <Lt>
+ </Le>
+ <Path>Price</Path>
+ <Int>100</Int>
+ <Le>
+ </Has>
+ <Path>Fabric</Path>
+ <EnumMember>org.example.Pattern/Red</EnumMember>
+ <Has>
+ </In>
+ <Path>Size</Path>
+ <Collection>
+ <String>XS</String>
+ <String>S</String>
+ <Collection>
+ </In> </
14.4.3 Arithmetic Operators
Annotations MAY use the following arithmetic expressions which evaluate to a numeric value. These expressions MAY be combined, and they MAY be used anywhere instead of a numeric expression of the appropriate type. The semantics and evaluation rules for each arithmetic expression is identical to the corresponding arithmetic operator defined in OData-URL.
@@ -2745,33 +2746,33 @@
Example 74:
-Add>
- <Path>StartDate</Path>
- <Path>Duration</Path>
- <Add>
- </Sub>
- <Path>Revenue</Path>
- <Path>Cost</Path>
- <Sub>
- </Neg>
- <Path>Height</Path>
- <Neg>
- </Mul>
- <Path>NetPrice</Path>
- <Path>TaxRate</Path>
- <Mul>
- </Div>
- <Path>Quantity</Path>
- <Path>QuantityPerParcel</Path>
- <Div>
- </DivBy>
- <Path>Quantity</Path>
- <Path>QuantityPerParcel</Path>
- <DivBy>
- </Mod>
- <Path>Quantity</Path>
- <Path>QuantityPerParcel</Path>
- <Mod> </
+Add>
+ <Path>StartDate</Path>
+ <Path>Duration</Path>
+ <Add>
+ </Sub>
+ <Path>Revenue</Path>
+ <Path>Cost</Path>
+ <Sub>
+ </Neg>
+ <Path>Height</Path>
+ <Neg>
+ </Mul>
+ <Path>NetPrice</Path>
+ <Path>TaxRate</Path>
+ <Mul>
+ </Div>
+ <Path>Quantity</Path>
+ <Path>QuantityPerParcel</Path>
+ <Div>
+ </DivBy>
+ <Path>Quantity</Path>
+ <Path>QuantityPerParcel</Path>
+ <DivBy>
+ </Mod>
+ <Path>Quantity</Path>
+ <Path>QuantityPerParcel</Path>
+ <Mod> </
14.4.4 Apply Client-Side Functions
The apply expression enables a value to be obtained by applying a client-side function. The apply expression MAY have operand expressions. The operand expressions are used as parameters to the client-side function.
@@ -2788,17 +2789,17 @@ OData-ABNF, i.e. Edm.Binary
as binaryValue
, Edm.Boolean
as booleanValue
etc.
Example 75:
-Annotation Term="org.example.display.DisplayName">
- <Apply Function="odata.concat">
- <String>Product: </String>
- <Path>ProductName</Path>
- <String> (</String>
- <Path>Available/Quantity</Path>
- <String> </String>
- <Path>Available/Unit</Path>
- <String> available)</String>
- <Apply>
- </Annotation> </
+Annotation Term="org.example.display.DisplayName">
+ <Apply Function="odata.concat">
+ <String>Product: </String>
+ <Path>ProductName</Path>
+ <String> (</String>
+ <Path>Available/Quantity</Path>
+ <String> </String>
+ <Path>Available/Unit</Path>
+ <String> available)</String>
+ <Apply>
+ </Annotation> </
ProductName
is of type String
, Quantity
in complex type Available
is of type Decimal
, and Unit
in Available
is of type enumeration, so the result of the Path
expression is represented as the member name of the enumeration value.
14.4.4.2 Function odata.fillUriTemplate
@@ -2810,34 +2811,34 @@ labeled element expressions that evaluate to a collection of complex types with two properties that are used in lexicographic order. The first property is used as key, the second property as value.
Example 76: assuming there are no special characters in values of the Name property of the Actor entity
-Apply Function="odata.fillUriTemplate">
- <String>http://host/someAPI/Actors/{actorName}/CV</String>
- <LabeledElement Name="actorName" Path="Actor/Name" />
- <Apply> </
+Apply Function="odata.fillUriTemplate">
+ <String>http://host/someAPI/Actors/{actorName}/CV</String>
+ <LabeledElement Name="actorName" Path="Actor/Name" />
+ <Apply> </
14.4.4.3 Function odata.matchesPattern
The odata.matchesPattern
client-side function takes two string expressions as arguments and returns a Boolean value. It is the counterpart of the identically named URL function OData-URL, section 5.1.1.7.1.
The function returns true if the second expression evaluates to an ECMAScript (JavaScript) regular expression and the result of the first argument expression matches that regular expression, using syntax and semantics of ECMAScript regular expressions.
Example 77: all non-empty FirstName
values not containing the letters b
, c
, or d
evaluate to true
-Apply Function="odata.matchesPattern">
- <Path>FirstName</Path>
- <String>^[^b-d]+$</String>
- <Apply> </
+Apply Function="odata.matchesPattern">
+ <Path>FirstName</Path>
+ <String>^[^b-d]+$</String>
+ <Apply> </
14.4.4.4 Function odata.uriEncode
The odata.uriEncode
client-side function takes one argument of primitive type and returns the URL-encoded OData literal that can be used as a key value in OData URLs or in the query part of OData URLs.
Note: string literals are surrounded by single quotes as required by the paren-style key syntax.
Example 78:
-Apply Function="odata.fillUriTemplate">
- <String>http://host/service/Genres({genreName})</String>
- <LabeledElement Name="genreName">
- <Apply Function="odata.uriEncode" >
- <Path>NameOfMovieGenre</Path>
- <Apply>
- </LabeledElement>
- </Apply> </
+Apply Function="odata.fillUriTemplate">
+ <String>http://host/service/Genres({genreName})</String>
+ <LabeledElement Name="genreName">
+ <Apply Function="odata.uriEncode" >
+ <Path>NameOfMovieGenre</Path>
+ <Apply>
+ </LabeledElement>
+ </Apply> </
14.4.5 Cast
The cast expression casts the value obtained from its single child expression to the specified type. The cast expression follows the same rules as the cast
canonical function defined in OData-URL.
@@ -2851,11 +2852,11 @@
Example 79:
-Annotation Term="org.example.display.Threshold">
- <Cast Type="Edm.Decimal">
- <Path>Average</Path>
- <Cast>
- </Annotation> </
+Annotation Term="org.example.display.Threshold">
+ <Cast Type="Edm.Decimal">
+ <Path>Average</Path>
+ <Cast>
+ </Annotation> </
14.4.6 Collection
The collection expression enables a value to be obtained from zero or more item expressions. The value calculated by the collection expression is the collection of the values calculated by each of the item expressions. The values of the child expressions MUST all be type compatible.
@@ -2865,13 +2866,13 @@ Expre
Example 80:
-Annotation Term="org.example.seo.SeoTerms">
- <Collection>
- <String>Product</String>
- <String>Supplier</String>
- <String>Customer</String>
- <Collection>
- </Annotation> </
+Annotation Term="org.example.seo.SeoTerms">
+ <Collection>
+ <String>Product</String>
+ <String>Supplier</String>
+ <String>Customer</String>
+ <Collection>
+ </Annotation> </
14.4.7 If-Then-Else
The if-then-else expression enables a value to be obtained by evaluating a condition expression. It MUST contain exactly three child expressions. There is one exception to this rule: if and only if the if-then-else expression is an item of a collection expression, the third child expression MAY be omitted, reducing it to an if-then expression. This can be used to conditionally add an element to a collection.
@@ -2885,13 +2886,13 @@ Expression edm:
Example 81: the condition is a value path expression referencing the Boolean property IsFemale
, whose value then determines the value of the edm:If
expression (or so it was long ago)
-Annotation Term="org.example.person.Gender">
- <If>
- <Path>IsFemale</Path>
- <String>Female</String>
- <String>Male</String>
- <If>
- </Annotation> </
+Annotation Term="org.example.person.Gender">
+ <If>
+ <Path>IsFemale</Path>
+ <String>Female</String>
+ <String>Male</String>
+ <If>
+ </Annotation> </
14.4.8 Is-Of
The is-of
expression checks whether the value obtained from its single child expression is compatible with the specified type. It returns true
if the child expression returns a type that is compatible with the specified type, and false
otherwise.
@@ -2903,11 +2904,11 @@ Expression
Example 82:
-Annotation Term="self.IsPreferredCustomer">
- <IsOf Type="self.PreferredCustomer">
- <Path>Customer</Path>
- <IsOf>
- </Annotation> </
+Annotation Term="self.IsPreferredCustomer">
+ <IsOf Type="self.PreferredCustomer">
+ <Path>Customer</Path>
+ <IsOf>
+ </Annotation> </
14.4.9 Labeled Element
The labeled element expression assigns a name to its single child expression. The value of the child expression can then be reused elsewhere with a labeled element reference expression.
@@ -2923,15 +2924,15 @@
Example 83:
-Annotation Term="org.example.display.DisplayName">
- <LabeledElement Name="CustomerFirstName" Path="FirstName" />
- <Annotation>
- </
-Annotation Term="org.example.display.DisplayName">
- <LabeledElement Name="CustomerFirstName">
- <Path>FirstName</Path>
- <LabeledElement>
- </Annotation> </
+Annotation Term="org.example.display.DisplayName">
+ <LabeledElement Name="CustomerFirstName" Path="FirstName" />
+ <Annotation>
+ </
+Annotation Term="org.example.display.DisplayName">
+ <LabeledElement Name="CustomerFirstName">
+ <Path>FirstName</Path>
+ <LabeledElement>
+ </Annotation> </
14.4.10 Labeled Element Reference
The labeled element reference expression MUST specify the qualified name of a labeled element expression in scope and returns the value of the identified labeled element expression as its value.
@@ -2941,9 +2942,9 @@
Example 84:
-Annotation Term="org.example.display.DisplayName">
- <LabeledElementReference>Model.CustomerFirstName</LabeledElementReference>
- <Annotation> </
+Annotation Term="org.example.display.DisplayName">
+ <LabeledElementReference>Model.CustomerFirstName</LabeledElementReference>
+ <Annotation> </
14.4.11 Null
The null expression indicates the absence of a value. The null expression MAY be annotated.
@@ -2953,17 +2954,17 @@ Expression
Example 85:
-Annotation Term="org.example.display.DisplayName">
- <Null/>
- <Annotation> </
+Annotation Term="org.example.display.DisplayName">
+ <Null/>
+ <Annotation> </
Example 86:
-Annotation Term="@UI.Address">
- <Null>
- <Annotation Term="self.Reason" String="Private" />
- <Null>
- </Annotation> </
+Annotation Term="@UI.Address">
+ <Null>
+ <Annotation Term="self.Reason" String="Private" />
+ <Null>
+ </Annotation> </
14.4.12 Record
The record expression enables a new entity type or complex type instance to be constructed.
@@ -2984,27 +2985,27 @@
Example 87: this annotation “morphs” the entity type from example 13 into a structured type with two structural properties GivenName
and Surname
and two navigation properties DirectSupervisor
and CostCenter
. The first three properties simply rename properties of the annotated entity type, the fourth adds a calculated navigation property that is pointing to a different service
-Annotations Target="org.example.Person">
- <Annotation Term="org.example.hcm.Employee">
- <Record Type="org.example.hcm.Manager">
- <Annotation Term="Core.Description" String="Annotation on record" />
- <PropertyValue Property="GivenName" Path="FirstName">
- <Annotation Term="Core.Description"
- < String="Annotation on record member" />
-PropertyValue>
- </PropertyValue Property="Surname" Path="LastName" />
- <PropertyValue Property="DirectSupervisor" Path="Manager" />
- <PropertyValue Property="CostCenter">
- <UrlRef>
- <Apply Function="odata.fillUriTemplate">
- <String>http://host/anotherservice/CostCenters('{ccid}')</String>
- <LabeledElement Name="ccid" Path="CostCenterID" />
- <Apply>
- </UrlRef>
- </PropertyValue>
- </Record>
- </Annotation>
- </Annotations> </
+Annotations Target="org.example.Person">
+ <Annotation Term="org.example.hcm.Employee">
+ <Record Type="org.example.hcm.Manager">
+ <Annotation Term="Core.Description" String="Annotation on record" />
+ <PropertyValue Property="GivenName" Path="FirstName">
+ <Annotation Term="Core.Description"
+ < String="Annotation on record member" />
+PropertyValue>
+ </PropertyValue Property="Surname" Path="LastName" />
+ <PropertyValue Property="DirectSupervisor" Path="Manager" />
+ <PropertyValue Property="CostCenter">
+ <UrlRef>
+ <Apply Function="odata.fillUriTemplate">
+ <String>http://host/anotherservice/CostCenters('{ccid}')</String>
+ <LabeledElement Name="ccid" Path="CostCenterID" />
+ <Apply>
+ </UrlRef>
+ </PropertyValue>
+ </Record>
+ </Annotation>
+ </Annotations> </
14.4.13 URL Reference
The URL reference expression enables a value to be obtained by sending a GET
request.
@@ -3018,24 +3019,24 @@ Expression
Example 88:
-Annotation Term="org.example.person.Supplier">
- <UrlRef>
- <Apply Function="odata.fillUriTemplate">
- <String>http://host/service/Suppliers({suppID})</String>
- <LabeledElement Name="suppID">
- <Apply Function="odata.uriEncode">
- <Path>SupplierId</Path>
- <Apply>
- </LabeledElement>
- </Apply>
- </UrlRef>
- </Annotation>
- </
-Annotation Term="Core.LongDescription">
- <UrlRef><String>http://host/wiki/HowToUse</String></UrlRef>
- <Annotation>
- </
-Annotation Term="Core.LongDescription" UrlRef="http://host/wiki/HowToUse" /> <
+Annotation Term="org.example.person.Supplier">
+ <UrlRef>
+ <Apply Function="odata.fillUriTemplate">
+ <String>http://host/service/Suppliers({suppID})</String>
+ <LabeledElement Name="suppID">
+ <Apply Function="odata.uriEncode">
+ <Path>SupplierId</Path>
+ <Apply>
+ </LabeledElement>
+ </Apply>
+ </UrlRef>
+ </Annotation>
+ </
+Annotation Term="Core.LongDescription">
+ <UrlRef><String>http://host/wiki/HowToUse</String></UrlRef>
+ <Annotation>
+ </
+Annotation Term="Core.LongDescription" UrlRef="http://host/wiki/HowToUse" /> <
15 Identifier and Path Values
@@ -3073,153 +3074,153 @@ 16 CSDL Ex
16.1 Products and Categories Example
Example 90:
-edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
- < xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
-edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
- <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
- <Annotation Term="Core.DefaultNamespace" />
- <edmx:Include>
- </edmx:Reference>
- </edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">
- <edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />
- <edmx:Reference>
- </edmx:DataServices>
- <Schema Namespace="ODataDemo">
- <EntityType Name="Product">
- <Key>
- <PropertyRef Name="ID" />
- <Key>
- </Property Name="ID" Type="Edm.Int32" Nullable="false" />
- <Property Name="Description" Type="Edm.String" >
- <Annotation Term="Core.IsLanguageDependent" />
- <Property>
- </Property Name="ReleaseDate" Type="Edm.Date" />
- <Property Name="DiscontinuedDate" Type="Edm.Date" />
- <Property Name="Rating" Type="Edm.Int32" />
- <Property Name="Price" Type="Edm.Decimal" Scale="variable">
- <Annotation Term="Measures.ISOCurrency" Path="Currency" />
- <Property>
- </Property Name="Currency" Type="Edm.String" MaxLength="3" />
- <NavigationProperty Name="Category" Type="ODataDemo.Category"
- < Nullable="false" Partner="Products" />
-NavigationProperty Name="Supplier" Type="ODataDemo.Supplier"
- < Partner="Products" />
-EntityType>
- </EntityType Name="Category">
- <Key>
- <PropertyRef Name="ID" />
- <Key>
- </Property Name="ID" Type="Edm.Int32" Nullable="false" />
- <Property Name="Name" Type="Edm.String" Nullable="false">
- <Annotation Term="Core.IsLanguageDependent" />
- <Property>
- </NavigationProperty Name="Products" Partner="Category"
- < Type="Collection(ODataDemo.Product)">
-OnDelete Action="Cascade" />
- <NavigationProperty>
- </EntityType>
- </EntityType Name="Supplier">
- <Key>
- <PropertyRef Name="ID" />
- <Key>
- </Property Name="ID" Type="Edm.String" Nullable="false" />
- <Property Name="Name" Type="Edm.String" />
- <Property Name="Address" Type="ODataDemo.Address" Nullable="false" />
- <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" />
- <NavigationProperty Name="Products" Partner="Supplier"
- < Type="Collection(ODataDemo.Product)" />
-EntityType>
- </EntityType Name="Country">
- <Key>
- <PropertyRef Name="Code" />
- <Key>
- </Property Name="Code" Type="Edm.String" MaxLength="2"
- < Nullable="false" />
-Property Name="Name" Type="Edm.String" />
- <EntityType>
- </ComplexType Name="Address">
- <Property Name="Street" Type="Edm.String" />
- <Property Name="City" Type="Edm.String" />
- <Property Name="State" Type="Edm.String" />
- <Property Name="ZipCode" Type="Edm.String" />
- <Property Name="CountryName" Type="Edm.String" />
- <NavigationProperty Name="Country" Type="ODataDemo.Country">
- <ReferentialConstraint Property="CountryName"
- < ReferencedProperty="Name" />
-NavigationProperty>
- </ComplexType>
- </Function Name="ProductsByRating">
- <Parameter Name="Rating" Type="Edm.Int32" />
- <ReturnType Type="Collection(ODataDemo.Product)" />
- <Function>
- </EntityContainer Name="DemoService">
- <EntitySet Name="Products" EntityType="ODataDemo.Product">
- <NavigationPropertyBinding Path="Category" Target="Categories" />
- <EntitySet>
- </EntitySet Name="Categories" EntityType="ODataDemo.Category">
- <NavigationPropertyBinding Path="Products" Target="Products" />
- <Annotation Term="Core.Description" String="Product Categories" />
- <EntitySet>
- </EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier">
- <NavigationPropertyBinding Path="Products" Target="Products" />
- <NavigationPropertyBinding Path="Address/Country"
- < Target="Countries" />
-Annotation Term="Core.OptimisticConcurrency">
- <Collection>
- <PropertyPath>Concurrency</PropertyPath>
- <Collection>
- </Annotation>
- </EntitySet>
- </Singleton Name="MainSupplier" Type="ODataDemo.Supplier">
- <NavigationPropertyBinding Path="Products" Target="Products" />
- <Annotation Term="Core.Description" String="Primary Supplier" />
- <Singleton>
- </EntitySet Name="Countries" EntityType="ODataDemo.Country" />
- <FunctionImport Name="ProductsByRating" EntitySet="Products"
- < Function="ODataDemo.ProductsByRating" />
-EntityContainer>
- </Schema>
- </edmx:DataServices>
- </edmx:Edmx> </
+edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
+ < xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
+edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
+ <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
+ <Annotation Term="Core.DefaultNamespace" />
+ <edmx:Include>
+ </edmx:Reference>
+ </edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">
+ <edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />
+ <edmx:Reference>
+ </edmx:DataServices>
+ <Schema Namespace="ODataDemo">
+ <EntityType Name="Product">
+ <Key>
+ <PropertyRef Name="ID" />
+ <Key>
+ </Property Name="ID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Description" Type="Edm.String" >
+ <Annotation Term="Core.IsLanguageDependent" />
+ <Property>
+ </Property Name="ReleaseDate" Type="Edm.Date" />
+ <Property Name="DiscontinuedDate" Type="Edm.Date" />
+ <Property Name="Rating" Type="Edm.Int32" />
+ <Property Name="Price" Type="Edm.Decimal" Scale="variable">
+ <Annotation Term="Measures.ISOCurrency" Path="Currency" />
+ <Property>
+ </Property Name="Currency" Type="Edm.String" MaxLength="3" />
+ <NavigationProperty Name="Category" Type="ODataDemo.Category"
+ < Nullable="false" Partner="Products" />
+NavigationProperty Name="Supplier" Type="ODataDemo.Supplier"
+ < Partner="Products" />
+EntityType>
+ </EntityType Name="Category">
+ <Key>
+ <PropertyRef Name="ID" />
+ <Key>
+ </Property Name="ID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Name" Type="Edm.String" Nullable="false">
+ <Annotation Term="Core.IsLanguageDependent" />
+ <Property>
+ </NavigationProperty Name="Products" Partner="Category"
+ < Type="Collection(ODataDemo.Product)">
+OnDelete Action="Cascade" />
+ <NavigationProperty>
+ </EntityType>
+ </EntityType Name="Supplier">
+ <Key>
+ <PropertyRef Name="ID" />
+ <Key>
+ </Property Name="ID" Type="Edm.String" Nullable="false" />
+ <Property Name="Name" Type="Edm.String" />
+ <Property Name="Address" Type="ODataDemo.Address" Nullable="false" />
+ <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" />
+ <NavigationProperty Name="Products" Partner="Supplier"
+ < Type="Collection(ODataDemo.Product)" />
+EntityType>
+ </EntityType Name="Country">
+ <Key>
+ <PropertyRef Name="Code" />
+ <Key>
+ </Property Name="Code" Type="Edm.String" MaxLength="2"
+ < Nullable="false" />
+Property Name="Name" Type="Edm.String" />
+ <EntityType>
+ </ComplexType Name="Address">
+ <Property Name="Street" Type="Edm.String" />
+ <Property Name="City" Type="Edm.String" />
+ <Property Name="State" Type="Edm.String" />
+ <Property Name="ZipCode" Type="Edm.String" />
+ <Property Name="CountryName" Type="Edm.String" />
+ <NavigationProperty Name="Country" Type="ODataDemo.Country">
+ <ReferentialConstraint Property="CountryName"
+ < ReferencedProperty="Name" />
+NavigationProperty>
+ </ComplexType>
+ </Function Name="ProductsByRating">
+ <Parameter Name="Rating" Type="Edm.Int32" />
+ <ReturnType Type="Collection(ODataDemo.Product)" />
+ <Function>
+ </EntityContainer Name="DemoService">
+ <EntitySet Name="Products" EntityType="ODataDemo.Product">
+ <NavigationPropertyBinding Path="Category" Target="Categories" />
+ <EntitySet>
+ </EntitySet Name="Categories" EntityType="ODataDemo.Category">
+ <NavigationPropertyBinding Path="Products" Target="Products" />
+ <Annotation Term="Core.Description" String="Product Categories" />
+ <EntitySet>
+ </EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier">
+ <NavigationPropertyBinding Path="Products" Target="Products" />
+ <NavigationPropertyBinding Path="Address/Country"
+ < Target="Countries" />
+Annotation Term="Core.OptimisticConcurrency">
+ <Collection>
+ <PropertyPath>Concurrency</PropertyPath>
+ <Collection>
+ </Annotation>
+ </EntitySet>
+ </Singleton Name="MainSupplier" Type="ODataDemo.Supplier">
+ <NavigationPropertyBinding Path="Products" Target="Products" />
+ <Annotation Term="Core.Description" String="Primary Supplier" />
+ <Singleton>
+ </EntitySet Name="Countries" EntityType="ODataDemo.Country" />
+ <FunctionImport Name="ProductsByRating" EntitySet="Products"
+ < Function="ODataDemo.ProductsByRating" />
+EntityContainer>
+ </Schema>
+ </edmx:DataServices>
+ </edmx:Edmx> </
16.2 Annotations for Products and Categories Example
Example 91:
-edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
- < Version="4.01">
-edmx:Reference Uri="http://host/service/$metadata">
- <edmx:Include Namespace="ODataDemo" Alias="target" />
- <edmx:Reference>
- </edmx:Reference Uri="http://somewhere/Vocabulary/V1">
- <edmx:Include Alias="Vocabulary1" Namespace="Some.Vocabulary.V1" />
- <edmx:Reference>
- </edmx:DataServices>
- <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
- < Namespace="External.Annotations">
-Annotations Target="ODataDemo.Supplier">
- <Annotation Term="Vocabulary1.EMail">
- <Null />
- <Annotation>
- </Annotation Term="Vocabulary1.AccountID" Path="ID" />
- <Annotation Term="Vocabulary1.Title" String="Supplier Info" />
- <Annotation Term="Vocabulary1.DisplayName">
- <Apply Function="odata.concat">
- <Path>Name</Path>
- <String> in </String>
- <Path>Address/CountryName</Path>
- <Apply>
- </Annotation>
- </Annotations>
- </Annotations Target="ODataDemo.Product">
- <Annotation Term="Vocabulary1.Tags">
- <Collection>
- <String>MasterData</String>
- <Collection>
- </Annotation>
- </Annotations>
- </Schema>
- </edmx:DataServices>
- </edmx:Edmx> </
+edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
+ < Version="4.01">
+edmx:Reference Uri="http://host/service/$metadata">
+ <edmx:Include Namespace="ODataDemo" Alias="target" />
+ <edmx:Reference>
+ </edmx:Reference Uri="http://somewhere/Vocabulary/V1">
+ <edmx:Include Alias="Vocabulary1" Namespace="Some.Vocabulary.V1" />
+ <edmx:Reference>
+ </edmx:DataServices>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
+ < Namespace="External.Annotations">
+Annotations Target="ODataDemo.Supplier">
+ <Annotation Term="Vocabulary1.EMail">
+ <Null />
+ <Annotation>
+ </Annotation Term="Vocabulary1.AccountID" Path="ID" />
+ <Annotation Term="Vocabulary1.Title" String="Supplier Info" />
+ <Annotation Term="Vocabulary1.DisplayName">
+ <Apply Function="odata.concat">
+ <Path>Name</Path>
+ <String> in </String>
+ <Path>Address/CountryName</Path>
+ <Apply>
+ </Annotation>
+ </Annotations>
+ </Annotations Target="ODataDemo.Product">
+ <Annotation Term="Vocabulary1.Tags">
+ <Collection>
+ <String>MasterData</String>
+ <Collection>
+ </Annotation>
+ </Annotations>
+ </Schema>
+ </edmx:DataServices>
+ </edmx:Edmx> </
17 Conformance
diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md
index 8fe7faf7c..754590c04 100644
--- a/docs/odata-csdl-xml/odata-csdl-xml.md
+++ b/docs/odata-csdl-xml/odata-csdl-xml.md
@@ -4191,9 +4191,14 @@ type specified by the navigation property are addressed via a [term-cast
segment](#TermCast).
::: example
-Example 64: model path addressing an annotation on a navigation property
+Example 64: model path segment addressing an annotation on a navigation property
+vs. term cast addressing an annotation on the resource addressed by the navigation property
```
-.../Items@Capabilities.InsertRestrictions/Insertable
+.../Items@Core.Description
+```
+
+```
+.../Items/@Core.Description
```
:::
diff --git a/odata-csdl/14 Vocabulary and Annotation.md b/odata-csdl/14 Vocabulary and Annotation.md
index 02ef3e82d..11712bf03 100644
--- a/odata-csdl/14 Vocabulary and Annotation.md
+++ b/odata-csdl/14 Vocabulary and Annotation.md
@@ -1351,9 +1351,14 @@ type specified by the navigation property are addressed via a [term-cast
segment](#TermCast).
::: example
-Example ##ex: model path addressing an annotation on a navigation property
+Example ##ex: model path segment addressing an annotation on a navigation property
+vs. term cast addressing an annotation on the resource addressed by the navigation property
```
-.../Items@Capabilities.InsertRestrictions/Insertable
+.../Items@Core.Description
+```
+
+```
+.../Items/@Core.Description
```
:::
From 34410b20de6b8ff5bc111480f1d14cc4d1598e4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Wed, 29 Nov 2023 17:39:00 +0100
Subject: [PATCH 06/22] ODATA-1553 (#174)
---
docs/odata-url-conventions/odata-url-conventions.html | 2 +-
docs/odata-url-conventions/odata-url-conventions.md | 3 +++
odata-url-conventions/5 Query Options.md | 3 +++
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html
index b1c4de110..f345701b0 100644
--- a/docs/odata-url-conventions/odata-url-conventions.html
+++ b/docs/odata-url-conventions/odata-url-conventions.html
@@ -1910,7 +1910,7 @@ 5.1.10 System Query Option $compute
The $compute
system query option allows clients to define computed properties that can be used in a $select
or within a $filter
or $orderby
expression.
The $compute
system query option is interpreted relative to the entity type or complex type of the resources identified by the resource path section of the URL.
-The value of $compute
is a comma-separated list of compute instructions, each consisting of a common expression followed by the keyword as
, followed by the name for the computed dynamic property. This name MUST differ from the names of declared or dynamic properties of the identified resources.
+The value of $compute
is a comma-separated list of compute instructions, each consisting of a common expression followed by the keyword as
, followed by the name for the computed dynamic property. This name MUST differ from the names of declared or dynamic properties of the identified resources. Services MAY support compute instructions that address dynamic properties added by other compute instructions within the same $compute
system query option, provided that the service can determine an evaluation sequence.
The OData-ABNF compute
syntax rule defines the formal grammar of the $compute
query option.
Computed properties SHOULD be included as dynamic properties in the result and MUST be included if $select
is specified with the computed property name, or star (*
).
diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md
index 89c0e757b..b913c1552 100644
--- a/docs/odata-url-conventions/odata-url-conventions.md
+++ b/docs/odata-url-conventions/odata-url-conventions.md
@@ -3780,6 +3780,9 @@ expression](#CommonExpressionSyntax) followed by the keyword `as`,
followed by the name for the computed dynamic property. This name MUST
differ from the names of declared or dynamic properties of the
identified resources.
+Services MAY support compute instructions that address
+dynamic properties added by other compute instructions within the same
+`$compute` system query option, provided that the service can determine an evaluation sequence.
The [OData-ABNF](#ODataABNF) `compute` syntax rule defines the formal
grammar of the `$compute` query option.
diff --git a/odata-url-conventions/5 Query Options.md b/odata-url-conventions/5 Query Options.md
index 2275ac6b4..6bb1854a0 100644
--- a/odata-url-conventions/5 Query Options.md
+++ b/odata-url-conventions/5 Query Options.md
@@ -2381,6 +2381,9 @@ expression](#CommonExpressionSyntax) followed by the keyword `as`,
followed by the name for the computed dynamic property. This name MUST
differ from the names of declared or dynamic properties of the
identified resources.
+Services MAY support compute instructions that address
+dynamic properties added by other compute instructions within the same
+`$compute` system query option, provided that the service can determine an evaluation sequence.
The [OData-ABNF](#ODataABNF) `compute` syntax rule defines the formal
grammar of the `$compute` query option.
From 00da66623b9ee5696962ed1ba99334011572b85c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Wed, 29 Nov 2023 17:49:41 +0100
Subject: [PATCH 07/22] ODATA-1555 (#173)
---
docs/odata-protocol/odata-protocol.html | 9 ++++--
docs/odata-protocol/odata-protocol.md | 36 +++++++++++++++-------
odata-protocol/11 Data Service Requests.md | 36 +++++++++++++++-------
3 files changed, 56 insertions(+), 25 deletions(-)
diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html
index d948d856f..40cca6ad2 100644
--- a/docs/odata-protocol/odata-protocol.html
+++ b/docs/odata-protocol/odata-protocol.html
@@ -1531,14 +1531,17 @@ GET http://host/service/Categories?$orderby=Products/$count
11.2.6.3 System Query Option $top
-The $top
system query option specifies a non-negative integer n that limits the number of items returned from a collection. The service returns the number of available items up to but not greater than the specified value n.
+The $top
system query option specifies a non-negative integer \(n\) that limits the number of items returned from a collection.
+Let \(A\) be a copy of the result set with a total order that extends any existing order of the result set but is otherwise chosen by the service. If no unique ordering is imposed through an $orderby
query option, the service MUST choose a stable ordering across requests that include $top
or $skip
.
+If \(A\) contains more than \(n\) instances, the result of \({\tt \$top}=n\) consists of the first \(n\) instances in \(A\). Otherwise, the result equals \(A\). The instances in the result are in the same order as they occur in \(A\).
Example 53: return only the first five products of the Products entity set
GET http://host/service/Products?$top=5
-If no unique ordering is imposed through an $orderby
query option, the service MUST impose a stable ordering across requests that include $top
.
11.2.6.4 System Query Option $skip
-The $skip
system query option specifies a non-negative integer n that excludes the first n items of the queried collection from the result. The service returns items starting at position n+1.
+The $skip
system query option specifies a non-negative integer \(n\) that excludes the first \(n\) items of the queried collection from the result.
+Let \(A\) be a copy of the result set with a total order that extends any existing order of the result set but is otherwise chosen by the service. If no unique ordering is imposed through an $orderby
query option, the service MUST choose a stable ordering across requests that include $top
or $skip
.
+If \(A\) contains \(n\) or fewer instances, the result of \({\tt \$skip}=n\) is empty. Otherwise, the first \(n\) instances in \(A\) are omitted from the result and all remaining instances are kept in the same order as they occur in \(A\).
Example 54: return products starting with the 6th product of the Products
entity set
GET http://host/service/Products?$skip=5
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md
index 8158cc6b0..4e4ff2d6d 100644
--- a/docs/odata-protocol/odata-protocol.md
+++ b/docs/odata-protocol/odata-protocol.md
@@ -3336,10 +3336,18 @@ GET http://host/service/Categories?$orderby=Products/$count
#### 11.2.6.3 System Query Option `$top`
-The `$top` system query option specifies a non-negative integer n that
-limits the number of items returned from a collection. The service
-returns the number of available items up to but not greater than the
-specified value n.
+The `$top` system query option specifies a non-negative integer $n$ that
+limits the number of items returned from a collection.
+
+Let $A$ be a copy of the result set with a total order that extends any
+existing order of the result set but is otherwise chosen by the service. If no
+unique ordering is imposed through an [`$orderby`](#SystemQueryOptionorderby)
+query option, the service MUST choose a stable
+ordering across requests that include `$top` or [`$skip`](#SystemQueryOptionskip).
+
+If $A$ contains more than $n$ instances, the result of ${\tt \$top}=n$
+consists of the first $n$ instances in $A$. Otherwise, the result equals $A$.
+The instances in the result are in the same order as they occur in $A$.
::: example
Example 53: return only the first five products of the Products entity
@@ -3349,15 +3357,21 @@ GET http://host/service/Products?$top=5
```
:::
-If no unique ordering is imposed through an
-[`$orderby`](#SystemQueryOptionorderby) query option, the service MUST
-impose a stable ordering across requests that include `$top`.
-
#### 11.2.6.4 System Query Option `$skip`
-The `$skip` system query option specifies a non-negative integer n that
-excludes the first n items of the queried collection from the result.
-The service returns items starting at position n+1.
+The `$skip` system query option specifies a non-negative integer $n$ that
+excludes the first $n$ items of the queried collection from the result.
+
+Let $A$ be a copy of the result set with a total order that extends any
+existing order of the result set but is otherwise chosen by the service. If no
+unique ordering is imposed through an [`$orderby`](#SystemQueryOptionorderby)
+query option, the service MUST choose a stable
+ordering across requests that include [`$top`](#SystemQueryOptiontop) or `$skip`.
+
+If $A$ contains $n$ or fewer instances, the result of ${\tt \$skip}=n$
+is empty. Otherwise, the first $n$ instances in $A$ are omitted
+from the result and all remaining instances are kept in the same order as
+they occur in $A$.
::: example
Example 54: return products starting with the 6th product of the
diff --git a/odata-protocol/11 Data Service Requests.md b/odata-protocol/11 Data Service Requests.md
index d356be30a..705ab2b59 100644
--- a/odata-protocol/11 Data Service Requests.md
+++ b/odata-protocol/11 Data Service Requests.md
@@ -802,10 +802,18 @@ GET http://host/service/Categories?$orderby=Products/$count
#### ##subsubsubsec System Query Option `$top`
-The `$top` system query option specifies a non-negative integer n that
-limits the number of items returned from a collection. The service
-returns the number of available items up to but not greater than the
-specified value n.
+The `$top` system query option specifies a non-negative integer $n$ that
+limits the number of items returned from a collection.
+
+Let $A$ be a copy of the result set with a total order that extends any
+existing order of the result set but is otherwise chosen by the service. If no
+unique ordering is imposed through an [`$orderby`](#SystemQueryOptionorderby)
+query option, the service MUST choose a stable
+ordering across requests that include `$top` or [`$skip`](#SystemQueryOptionskip).
+
+If $A$ contains more than $n$ instances, the result of ${\tt \$top}=n$
+consists of the first $n$ instances in $A$. Otherwise, the result equals $A$.
+The instances in the result are in the same order as they occur in $A$.
::: example
Example ##ex: return only the first five products of the Products entity
@@ -815,15 +823,21 @@ GET http://host/service/Products?$top=5
```
:::
-If no unique ordering is imposed through an
-[`$orderby`](#SystemQueryOptionorderby) query option, the service MUST
-impose a stable ordering across requests that include `$top`.
-
#### ##subsubsubsec System Query Option `$skip`
-The `$skip` system query option specifies a non-negative integer n that
-excludes the first n items of the queried collection from the result.
-The service returns items starting at position n+1.
+The `$skip` system query option specifies a non-negative integer $n$ that
+excludes the first $n$ items of the queried collection from the result.
+
+Let $A$ be a copy of the result set with a total order that extends any
+existing order of the result set but is otherwise chosen by the service. If no
+unique ordering is imposed through an [`$orderby`](#SystemQueryOptionorderby)
+query option, the service MUST choose a stable
+ordering across requests that include [`$top`](#SystemQueryOptiontop) or `$skip`.
+
+If $A$ contains $n$ or fewer instances, the result of ${\tt \$skip}=n$
+is empty. Otherwise, the first $n$ instances in $A$ are omitted
+from the result and all remaining instances are kept in the same order as
+they occur in $A$.
::: example
Example ##ex: return products starting with the 6th product of the
From cac53eb05172c7a3c5ca96d2281e9ba09765a658 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Wed, 29 Nov 2023 17:53:42 +0100
Subject: [PATCH 08/22] ODATA-1584 (#177)
Co-authored-by: Ralf Handl
---
docs/odata-protocol/odata-protocol.html | 2 +-
docs/odata-protocol/odata-protocol.md | 3 ++-
odata-protocol/11 Data Service Requests.md | 3 ++-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html
index 40cca6ad2..4ba419955 100644
--- a/docs/odata-protocol/odata-protocol.html
+++ b/docs/odata-protocol/odata-protocol.html
@@ -1309,7 +1309,7 @@ $select
and $expand
system query options enable the client to specify the set of structural properties and navigation properties to include in a response. The service MAY include additional properties not specified in $select
and $expand
, including properties not defined in the metadata document.
11.2.5.1 System Query Option $select
The $select
system query option requests that the service return only the properties, dynamic properties, actions and functions explicitly requested by the client. The service returns the specified content, if available, along with any available expanded navigation or stream properties, and MAY return additional information.
-The value of the $select
query option is a comma-separated list of properties, qualified action names, qualified function names, the star operator (*
), or the star operator prefixed with the namespace or alias of the schema in order to specify all operations defined in the schema. Only aliases defined in the metadata document of the service can be used in URLs.
+The value of the $select
query option is a comma-separated list of paths that end with properties, non-entity-valued instance annotations, qualified action names, or qualified function names, as well as of the star operator (*
), or the star operator prefixed with the namespace or alias of the schema in order to specify all operations defined in the schema. Only aliases defined in the metadata document of the service can be used in URLs.
Example 33: request only the Rating
and ReleaseDate
for the matching Products
GET http://host/service/Products?$select=Rating,ReleaseDate
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md
index 4e4ff2d6d..de17ee23c 100644
--- a/docs/odata-protocol/odata-protocol.md
+++ b/docs/odata-protocol/odata-protocol.md
@@ -2839,7 +2839,8 @@ returns the specified content, if available, along with any available
and MAY return additional information.
The value of the `$select` query option is a comma-separated list of
-properties, qualified action names, qualified function names, the star
+paths that end with properties, non-entity-valued instance annotations,
+qualified action names, or qualified function names, as well as of the star
operator (`*`), or the star operator prefixed with the namespace or
alias of the schema in order to specify all operations defined in the
schema. Only aliases defined in the metadata document of the service can
diff --git a/odata-protocol/11 Data Service Requests.md b/odata-protocol/11 Data Service Requests.md
index 705ab2b59..ebfe0e577 100644
--- a/odata-protocol/11 Data Service Requests.md
+++ b/odata-protocol/11 Data Service Requests.md
@@ -305,7 +305,8 @@ returns the specified content, if available, along with any available
and MAY return additional information.
The value of the `$select` query option is a comma-separated list of
-properties, qualified action names, qualified function names, the star
+paths that end with properties, non-entity-valued instance annotations,
+qualified action names, or qualified function names, as well as of the star
operator (`*`), or the star operator prefixed with the namespace or
alias of the schema in order to specify all operations defined in the
schema. Only aliases defined in the metadata document of the service can
From 4993adbead02d71b4748cc0e4b23e2cc8caad7c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Wed, 29 Nov 2023 17:56:53 +0100
Subject: [PATCH 09/22] ODATA-1591 (#172)
---
docs/odata-protocol/odata-protocol.html | 2 +-
docs/odata-protocol/odata-protocol.md | 2 +-
odata-protocol/11 Data Service Requests.md | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html
index 4ba419955..507bf5dfb 100644
--- a/docs/odata-protocol/odata-protocol.html
+++ b/docs/odata-protocol/odata-protocol.html
@@ -1611,7 +1611,7 @@ Entities are stably addressable using their canonical URL and are not accessible using an ordinal index.
Example 64: the first address in a list of addresses for MainSupplier
-GET http://host/service/Suppliers(MainSupplier)/Addresses/0
+GET http://host/service/MainSupplier/Addresses/0
11.2.7 Requesting Related Entities
To request related entities according to a particular relationship, the client issues a GET
request to the source entity’s request URL, followed by a forward slash and the name of the navigation property representing the relationship.
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md
index de17ee23c..9cf70d6eb 100644
--- a/docs/odata-protocol/odata-protocol.md
+++ b/docs/odata-protocol/odata-protocol.md
@@ -3557,7 +3557,7 @@ accessible using an ordinal index.
::: example
Example 64: the first address in a list of addresses for `MainSupplier`
```
-GET http://host/service/Suppliers(MainSupplier)/Addresses/0
+GET http://host/service/MainSupplier/Addresses/0
```
:::
diff --git a/odata-protocol/11 Data Service Requests.md b/odata-protocol/11 Data Service Requests.md
index ebfe0e577..20ecf449b 100644
--- a/odata-protocol/11 Data Service Requests.md
+++ b/odata-protocol/11 Data Service Requests.md
@@ -1023,7 +1023,7 @@ accessible using an ordinal index.
::: example
Example ##ex: the first address in a list of addresses for `MainSupplier`
```
-GET http://host/service/Suppliers(MainSupplier)/Addresses/0
+GET http://host/service/MainSupplier/Addresses/0
```
:::
From 2b014dba5e1a4c5cac1b46fe233fb565f723afca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Wed, 29 Nov 2023 17:59:21 +0100
Subject: [PATCH 10/22] ODATA-1592 (#94)
---
docs/odata-csdl-json/odata-csdl-json.html | 8 ++--
docs/odata-csdl-json/odata-csdl-json.md | 8 ++--
docs/odata-csdl-xml/odata-csdl-xml.html | 52 ++++++++++++-----------
docs/odata-csdl-xml/odata-csdl-xml.md | 12 ++++--
odata-csdl/4 CSDL Document.md | 20 +++++----
5 files changed, 56 insertions(+), 44 deletions(-)
diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html
index 516403bc1..b9c650b22 100644
--- a/docs/odata-csdl-json/odata-csdl-json.html
+++ b/docs/odata-csdl-json/odata-csdl-json.html
@@ -826,10 +826,10 @@
{
...
"$Reference": {
- "http://vocabs.odata.org/capabilities/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
...
},
- "http://vocabs.odata.org/core/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
...
},
"http://example.org/display/v1": {
@@ -863,7 +863,7 @@ $Alias
{
...
"$Reference": {
- "http://vocabs.odata.org/capabilities/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
"$Include": [
{
"$Namespace": "Org.OData.Capabilities.V1",
@@ -871,7 +871,7 @@ $Alias
}
]
},
- "http://vocabs.odata.org/core/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
"$Include": [
{
"$Namespace": "Org.OData.Core.V1",
diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md
index b66d706d2..05f9a52e9 100644
--- a/docs/odata-csdl-json/odata-csdl-json.md
+++ b/docs/odata-csdl-json/odata-csdl-json.md
@@ -985,10 +985,10 @@ Example 8: references to other CSDL documents
{
...
"$Reference": {
- "http://vocabs.odata.org/capabilities/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
...
},
- "http://vocabs.odata.org/core/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
...
},
"http://example.org/display/v1": {
@@ -1063,7 +1063,7 @@ vocabulary terms
{
...
"$Reference": {
- "http://vocabs.odata.org/capabilities/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
"$Include": [
{
"$Namespace": "Org.OData.Capabilities.V1",
@@ -1071,7 +1071,7 @@ vocabulary terms
}
]
},
- "http://vocabs.odata.org/core/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
"$Include": [
{
"$Namespace": "Org.OData.Core.V1",
diff --git a/docs/odata-csdl-xml/odata-csdl-xml.html b/docs/odata-csdl-xml/odata-csdl-xml.html
index bf05facbe..5bb609002 100644
--- a/docs/odata-csdl-xml/odata-csdl-xml.html
+++ b/docs/odata-csdl-xml/odata-csdl-xml.html
@@ -804,17 +804,19 @@ Attri
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
< Version="4.0">
-edmx:Reference Uri="http://vocabs.odata.org/capabilities/v1">
- <
- ...edmx:Reference>
- </edmx:Reference Uri="http://vocabs.odata.org/core/v1">
- <
- ...edmx:Reference>
- </edmx:Reference Uri="http://example.org/display/v1">
- <
- ...edmx:Reference>
- </edmx:DataServices>...</edmx:DataServices>
- <edmx:Edmx> </
+edmx:Reference
+ < Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml">
+
+ ...edmx:Reference>
+ </edmx:Reference
+ < Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
+
+ ...edmx:Reference>
+ </edmx:Reference Uri="http://example.org/display/v1">
+ <
+ ...edmx:Reference>
+ </edmx:DataServices>...</edmx:DataServices>
+ <edmx:Edmx> </
4.2 Included Schema
A reference MAY include zero or more schemas from the referenced document.
@@ -840,19 +842,21 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
< Version="4.0">
-edmx:Reference Uri="http://vocabs.odata.org/capabilities/v1">
- <edmx:Include Namespace="Org.OData.Capabilities.V1" />
- <edmx:Reference>
- </edmx:Reference Uri="http://vocabs.odata.org/core/v1">
- <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
- <Annotation Term="Core.DefaultNamespace" />
- <edmx:Include>
- </edmx:Reference>
- </edmx:Reference Uri="http://example.org/display/v1">
- <edmx:Include Alias="UI" Namespace="org.example.display" />
- <edmx:Reference>
- </edmx:DataServices>...</edmx:DataServices>
- <edmx:Edmx> </
+edmx:Reference
+ < Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml">
+edmx:Include Namespace="Org.OData.Capabilities.V1" />
+ <edmx:Reference>
+ </edmx:Reference
+ < Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
+edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
+ <Annotation Term="Core.DefaultNamespace" />
+ <edmx:Include>
+ </edmx:Reference>
+ </edmx:Reference Uri="http://example.org/display/v1">
+ <edmx:Include Alias="UI" Namespace="org.example.display" />
+ <edmx:Reference>
+ </edmx:DataServices>...</edmx:DataServices>
+ <edmx:Edmx> </
4.3 Included Annotations
In addition to including whole schemas with all model constructs defined within that schema, a reference may include annotations.
diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md
index 754590c04..d3587a01e 100644
--- a/docs/odata-csdl-xml/odata-csdl-xml.md
+++ b/docs/odata-csdl-xml/odata-csdl-xml.md
@@ -929,10 +929,12 @@ Example 8: references to other CSDL documents
-
+
...
-
+
...
@@ -1009,10 +1011,12 @@ vocabulary terms
-
+
-
+
diff --git a/odata-csdl/4 CSDL Document.md b/odata-csdl/4 CSDL Document.md
index c119d00bc..7674fb830 100644
--- a/odata-csdl/4 CSDL Document.md
+++ b/odata-csdl/4 CSDL Document.md
@@ -125,10 +125,10 @@ Example ##ex: references to other CSDL documents
{
...
"$Reference": {
- "http://vocabs.odata.org/capabilities/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
...
},
- "http://vocabs.odata.org/core/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
...
},
"http://example.org/display/v1": {
@@ -169,10 +169,12 @@ Example ##ex: references to other CSDL documents
-
+
...
-
+
...
@@ -252,7 +254,7 @@ vocabulary terms
{
...
"$Reference": {
- "http://vocabs.odata.org/capabilities/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
"$Include": [
{
"$Namespace": "Org.OData.Capabilities.V1",
@@ -260,7 +262,7 @@ vocabulary terms
}
]
},
- "http://vocabs.odata.org/core/v1": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
"$Include": [
{
"$Namespace": "Org.OData.Core.V1",
@@ -310,10 +312,12 @@ vocabulary terms
-
+
-
+
From 2abb246d78b3778f833e7a7d6f0f23a66e097bde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Wed, 29 Nov 2023 18:02:40 +0100
Subject: [PATCH 11/22] ODATA-1602: Example 39 applies to Term (#186)
---
docs/odata-csdl-json/odata-csdl-json.html | 13 +++++++------
docs/odata-csdl-json/odata-csdl-json.md | 3 ++-
odata-csdl/14 Vocabulary and Annotation.md | 3 ++-
3 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html
index b9c650b22..410f6e9cd 100644
--- a/docs/odata-csdl-json/odata-csdl-json.html
+++ b/docs/odata-csdl-json/odata-csdl-json.html
@@ -2200,12 +2200,13 @@ $AppliesTo
"$Type": "Core.Tag",
"$DefaultValue": true,
"$AppliesTo": [
- "Property"
- ],
- "@Core.Description": "Properties and terms annotated with this term
-MUST contain a valid URL",
- "@Core.RequiresType": "Edm.String"
-}
+ "Property",
+ "Term"
+ ],
+ "@Core.Description": "Properties and terms annotated with this term
+MUST contain a valid URL",
+ "@Core.RequiresType": "Edm.String"
+}
14.2 Annotation
An annotation applies a term to a model element and defines how to calculate a value for the term application. Both term and model element MUST be in scope. Section 14.1.2 specifies which model elements MAY be annotated with a term.
diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md
index 05f9a52e9..1a2219d5d 100644
--- a/docs/odata-csdl-json/odata-csdl-json.md
+++ b/docs/odata-csdl-json/odata-csdl-json.md
@@ -3700,7 +3700,8 @@ are defined in [OData-VocCore](#ODataVocCore))
"$Type": "Core.Tag",
"$DefaultValue": true,
"$AppliesTo": [
- "Property"
+ "Property",
+ "Term"
],
"@Core.Description": "Properties and terms annotated with this term
MUST contain a valid URL",
diff --git a/odata-csdl/14 Vocabulary and Annotation.md b/odata-csdl/14 Vocabulary and Annotation.md
index 11712bf03..af862b3e4 100644
--- a/odata-csdl/14 Vocabulary and Annotation.md
+++ b/odata-csdl/14 Vocabulary and Annotation.md
@@ -346,7 +346,8 @@ are defined in [OData-VocCore](#ODataVocCore))
"$Type": "Core.Tag",
"$DefaultValue": true,
"$AppliesTo": [
- "Property"
+ "Property",
+ "Term"
],
"@Core.Description": "Properties and terms annotated with this term
MUST contain a valid URL",
From eaf27e931212509a9d79ea1e11fd15343efa5689 Mon Sep 17 00:00:00 2001
From: Ralf Handl
Date: Wed, 29 Nov 2023 18:11:04 +0100
Subject: [PATCH 12/22] ODATA-1398 (#195)
---
docs/odata-json-format/odata-json-format.html | 55 ++++++++++---------
docs/odata-json-format/odata-json-format.md | 5 ++
docs/odata-protocol/odata-protocol.html | 16 +++---
docs/odata-protocol/odata-protocol.md | 34 ++++++------
.../19 Batch Requests and Responses.md | 5 ++
odata-protocol/11.7 Batch Requests.md | 34 ++++++------
6 files changed, 82 insertions(+), 67 deletions(-)
diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html
index 0b889c779..2336c1fb6 100644
--- a/docs/odata-json-format/odata-json-format.html
+++ b/docs/odata-json-format/odata-json-format.html
@@ -1673,32 +1673,37 @@ 19.5 B
Relative URLs in a response object follow the rules for relative URLs based on the request URL of the corresponding request. Especially: URLs in responses MUST NOT contain $
-prefixed request identifiers.
Example 51: referencing the batch request example 48 above, assume all the requests except the final query request succeed. In this case the response would be
-{
-"responses": [
- {
- "id": "0",
- "status": 200,
- "body": <JSON representation of the Customer entity with key ALFKI>
- },
+ HTTP/1.1 200 OK
+OData-Version: 4.01
+Content-Length: ####
+Content-Type: application/json
+
+{
+"responses": [
{
- "id": "1",
- "status": 204
- },
- {
- "id": "2",
- "status": 201,
- "headers": {
- "location": "http://host/service.svc/Customer('POIUY')"
- },
- "body": <JSON representation of the new Customer entity>
- },
- {
- "id": "3",
- "status": 404,
- "body": <Error message>
- }
- ]
- }
+"id": "0",
+ "status": 200,
+ "body": <JSON representation of the Customer entity with key ALFKI>
+ },
+ {
+ "id": "1",
+ "status": 204
+ },
+ {
+ "id": "2",
+ "status": 201,
+ "headers": {
+ "location": "http://host/service.svc/Customer('POIUY')"
+ },
+ "body": <JSON representation of the new Customer entity>
+ },
+ {
+ "id": "3",
+ "status": 404,
+ "body": <Error message>
+ }
+ ]
+ }
19.6 Asynchronous Batch Requests
A batch request that specifies the respond-async
preference MAY be executed asynchronously. This means that the “outer” batch request is executed asynchronously; this preference does not automatically cascade down to the individual requests within the batch. After successful execution of the batch request the response to the batch request is returned in the body of a response to an interrogation request against the status monitor resource URL, see section “Asynchronous Requests” in OData-Protocol.
diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md
index b5eb8eb96..bcf80d345 100644
--- a/docs/odata-json-format/odata-json-format.md
+++ b/docs/odata-json-format/odata-json-format.md
@@ -3198,6 +3198,11 @@ Example 51: referencing the batch request [example 48](#batchRequest) above, ass
the requests except the final query request succeed. In this case the
response would be
```json
+HTTP/1.1 200 OK
+OData-Version: 4.01
+Content-Length: ####
+Content-Type: application/json
+
{
"responses": [
{
diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html
index 507bf5dfb..2e34909dc 100644
--- a/docs/odata-protocol/odata-protocol.html
+++ b/docs/odata-protocol/odata-protocol.html
@@ -2234,6 +2234,8 @@ 11.7 B
Batch requests are submitted as a single HTTP POST
request to the batch endpoint of a service, located at the URL $batch
relative to the service root.
Individual requests within a batch request are evaluated according to the same semantics used when the request appears outside the context of a batch request.
A batch request is represented using either the multipart batch format defined in this document or the JSON batch format defined in OData-JSON.
+If the set of request headers of a batch request are valid the service MUST return a 200 OK
HTTP response code to indicate that the batch request was accepted for processing, even if the processing is yet to be completed. The individual requests within the body of the batch request may be processed as soon as they are received, this enables clients to stream batch requests, and batch implementations to stream the results.
+If the service receives a batch request with an invalid set of headers it MUST return a 4xx response code
and perform no further processing of the batch request.
11.7.1 Batch Request Headers
A batch request using the multipart batch format MUST contain a Content-Type
header specifying a content type of multipart/mixed
and a boundary
parameter as defined in RFC2046.
@@ -2257,8 +2259,6 @@ Accept
header specifying the desired batch response format, either multipart/mixed
or application/json
. If no Accept
header is provided, services SHOULD respond with the content type of the request.
-
If the set of request headers of a batch request are valid the service MUST return a 200 OK
HTTP response code to indicate that the batch request was accepted for processing, but the processing is yet to be completed. The individual requests within the body of the batch request may subsequently fail or be malformed; however, this enables batch implementations to stream the results.
-If the service receives a batch request with an invalid set of headers it MUST return a 4xx response code
and perform no further processing of the batch request.
11.7.2 Request Dependencies
Requests within a batch may have dependencies on other requests according to the particular batch format.
In the JSON format, requests may explicitly declare a dependency on other requests that must be successfully processed before the current request. In addition, requests may be specified as part of an atomicity group whose members MUST either all succeed, or all fail. If a request fails, then any dependent requests within the JSON format return 424 Failed Dependency
.
@@ -2470,7 +2470,7 @@ Data Service Requests. Relative URLs in each individual response are relative to the request URL of the corresponding individual request. URLs in responses MUST NOT contain $
-prefixed request identifiers.
Example 107: referencing the batch request example 101 above, assume all the requests except the final query request succeed. In this case the response would be
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
OData-Version: 4.0
Content-Length: ####
Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -2478,7 +2478,7 @@
When interrogating the monitor URL only the first request in the batch has finished processing and all the remaining requests are still being processed. Note that the actual multipart batch response itself is contained in an application/http
wrapper as it is a response to a status monitor resource:
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
Content-Type: application/http
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
OData-Version: 4.0
Content-Length: ####
Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -2539,7 +2539,7 @@
After some time the client makes a second request using the returned monitor URL, not explicitly accepting application/http
. The batch is completely processed and the response is the final result.
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
AsyncResult: 200
OData-Version: 4.0
Content-Length: ####
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md
index 9cf70d6eb..109bb298a 100644
--- a/docs/odata-protocol/odata-protocol.md
+++ b/docs/odata-protocol/odata-protocol.md
@@ -5684,6 +5684,17 @@ A batch request is represented using either the [multipart batch
format](#MultipartBatchFormat) defined in this document or the JSON
batch format defined in [OData-JSON](#ODataJSON).
+If the set of request headers of a batch request are valid the service
+MUST return a [`200 OK`](#ResponseCode200OK) HTTP response code to
+indicate that the batch request was accepted for processing, even if the
+processing is yet to be completed. The individual requests within the
+body of the batch request may be processed as soon as they are received,
+this enables clients to stream batch requests, and batch implementations to stream the results.
+
+If the service receives a batch request with an invalid set of headers
+it MUST return a [`4xx response code`](#ClientErrorResponses) and
+perform no further processing of the batch request.
+
### 11.7.1 Batch Request Headers
A batch request using the [multipart batch
@@ -5726,17 +5737,6 @@ specifying the desired batch response format, either `multipart/mixed`
or `application/json`. If no `Accept` header is provided, services
SHOULD respond with the content type of the request.
-If the set of request headers of a batch request are valid the service
-MUST return a [`200 OK`](#ResponseCode200OK) HTTP response code to
-indicate that the batch request was accepted for processing, but the
-processing is yet to be completed. The individual requests within the
-body of the batch request may subsequently fail or be malformed;
-however, this enables batch implementations to stream the results.
-
-If the service receives a batch request with an invalid set of headers
-it MUST return a [`4xx response code`](#ClientErrorResponses) and
-perform no further processing of the batch request.
-
### 11.7.2 Request Dependencies
Requests within a batch may have dependencies on other requests
@@ -6131,7 +6131,7 @@ Example 107: referencing the batch request example 101 above, assume all
the requests except the final query request succeed. In this case the
response would be
```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
OData-Version: 4.0
Content-Length: ####
Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -6139,7 +6139,7 @@ Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
--b_243234_25424_ef_892u748
Content-Type: application/http
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: ###
@@ -6219,10 +6219,10 @@ processed. Note that the actual multipart batch response itself is
contained in an `application/http` wrapper as it is a response to a
status monitor resource:
```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
Content-Type: application/http
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
OData-Version: 4.0
Content-Length: ####
Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -6230,7 +6230,7 @@ Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
--b_243234_25424_ef_892u748
Content-Type: application/http
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: ###
@@ -6250,7 +6250,7 @@ After some time the client makes a second request using the returned
monitor URL, not explicitly accepting
`application/http`. The batch is completely processed and the response is the final result.
```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
AsyncResult: 200
OData-Version: 4.0
Content-Length: ####
diff --git a/odata-json-format/19 Batch Requests and Responses.md b/odata-json-format/19 Batch Requests and Responses.md
index 960fd1201..fffa230cd 100644
--- a/odata-json-format/19 Batch Requests and Responses.md
+++ b/odata-json-format/19 Batch Requests and Responses.md
@@ -360,6 +360,11 @@ Example ##ex: referencing the batch request [example ##batchRequest] above, assu
the requests except the final query request succeed. In this case the
response would be
```json
+HTTP/1.1 200 OK
+OData-Version: 4.01
+Content-Length: ####
+Content-Type: application/json
+
{
"responses": [
{
diff --git a/odata-protocol/11.7 Batch Requests.md b/odata-protocol/11.7 Batch Requests.md
index cd923e317..0363af910 100644
--- a/odata-protocol/11.7 Batch Requests.md
+++ b/odata-protocol/11.7 Batch Requests.md
@@ -19,6 +19,17 @@ A batch request is represented using either the [multipart batch
format](#MultipartBatchFormat) defined in this document or the JSON
batch format defined in [OData-JSON](#ODataJSON).
+If the set of request headers of a batch request are valid the service
+MUST return a [`200 OK`](#ResponseCode200OK) HTTP response code to
+indicate that the batch request was accepted for processing, even if the
+processing is yet to be completed. The individual requests within the
+body of the batch request may be processed as soon as they are received,
+this enables clients to stream batch requests, and batch implementations to stream the results.
+
+If the service receives a batch request with an invalid set of headers
+it MUST return a [`4xx response code`](#ClientErrorResponses) and
+perform no further processing of the batch request.
+
### ##subsubsec Batch Request Headers
A batch request using the [multipart batch
@@ -61,17 +72,6 @@ specifying the desired batch response format, either `multipart/mixed`
or `application/json`. If no `Accept` header is provided, services
SHOULD respond with the content type of the request.
-If the set of request headers of a batch request are valid the service
-MUST return a [`200 OK`](#ResponseCode200OK) HTTP response code to
-indicate that the batch request was accepted for processing, but the
-processing is yet to be completed. The individual requests within the
-body of the batch request may subsequently fail or be malformed;
-however, this enables batch implementations to stream the results.
-
-If the service receives a batch request with an invalid set of headers
-it MUST return a [`4xx response code`](#ClientErrorResponses) and
-perform no further processing of the batch request.
-
### ##subsubsec Request Dependencies
Requests within a batch may have dependencies on other requests
@@ -468,7 +468,7 @@ Example ##ex: referencing the batch request example 101 above, assume all
the requests except the final query request succeed. In this case the
response would be
```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
OData-Version: 4.0
Content-Length: ####
Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -476,7 +476,7 @@ Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
--b_243234_25424_ef_892u748
Content-Type: application/http
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: ###
@@ -556,10 +556,10 @@ processed. Note that the actual multipart batch response itself is
contained in an `application/http` wrapper as it is a response to a
status monitor resource:
```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
Content-Type: application/http
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
OData-Version: 4.0
Content-Length: ####
Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
@@ -567,7 +567,7 @@ Content-Type: multipart/mixed; boundary=b_243234_25424_ef_892u748
--b_243234_25424_ef_892u748
Content-Type: application/http
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: ###
@@ -587,7 +587,7 @@ After some time the client makes a second request using the returned
monitor URL, not explicitly accepting
`application/http`. The batch is completely processed and the response is the final result.
```
-HTTP/1.1 200 Ok
+HTTP/1.1 200 OK
AsyncResult: 200
OData-Version: 4.0
Content-Length: ####
From 971d7f3a4b24f8fffdfeba1abc8715c1dc7589f8 Mon Sep 17 00:00:00 2001
From: Ralf Handl
Date: Wed, 29 Nov 2023 18:15:25 +0100
Subject: [PATCH 13/22] ODATA-1563 (#192)
---
docs/odata-url-conventions/odata-url-conventions.html | 2 +-
docs/odata-url-conventions/odata-url-conventions.md | 4 ++--
odata-url-conventions/4 Resource Path.md | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html
index f345701b0..c46720cab 100644
--- a/docs/odata-url-conventions/odata-url-conventions.html
+++ b/docs/odata-url-conventions/odata-url-conventions.html
@@ -744,7 +744,7 @@ 4.11 Addressing Derived Types
Any resource path or path expression identifying a collection of entities or complex type instances can be appended with a type-cast segment, that is a path segment containing the qualified name of a type derived from the declared item type of the collection. The result will be restricted to instances of the derived type and may be empty.
-Any resource path or path expression identifying a single entity or complex type instance can be appended with a type-cast segment containing the qualified name of a type derived from the declared type of the identified resource. If used in a resource path and the identified resource is not an instance of the derived type, the request will result in a 404 Not Found
response. If used in a path expression that is part of a Boolean expression, the type cast will evaluate to null
.
+Any resource path or path expression identifying a single entity or complex type instance can be appended with a type-cast segment containing the qualified name of a type derived from the declared type of the identified resource. If used in a resource path and the identified resource is not an instance of the derived type, the request will result in a 404 Not Found
response. If used in a path expression, the type cast will evaluate to null
.
Services MAY additionally support the use of the unqualified name of a derived type in a URL by defining one or more default namespaces through the Core.DefaultNamespace
term defined in OData-VocCore. For more information on default namespaces, see Default Namespaces in OData-Protocol.
Services MAY also support treating an instance as a type outside of the type hierarchy using the same syntax and semantics as when addressing a derived type. In this case, the set and values of properties of the addressed type may be different than the properties of the source type. The set of such possible target types outside of the type hierarchy SHOULD be called out using the Core.MayImplement
annotation term, defined in OData-VocCore.
diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md
index b913c1552..df2a97f34 100644
--- a/docs/odata-url-conventions/odata-url-conventions.md
+++ b/docs/odata-url-conventions/odata-url-conventions.md
@@ -1118,8 +1118,8 @@ complex type instance can be appended with a type-cast segment containing the
qualified name of a type derived from the declared type of the
identified resource. If used in a resource path and the identified
resource is not an instance of the derived type, the request will result
-in a `404 Not Found` response. If used in a path expression that is part
-of a Boolean expression, the type cast will evaluate to `null`.
+in a `404 Not Found` response. If used in a path expression,
+the type cast will evaluate to `null`.
Services MAY additionally support the use of the unqualified name of a
derived type in a URL by defining one or more default namespaces through
diff --git a/odata-url-conventions/4 Resource Path.md b/odata-url-conventions/4 Resource Path.md
index f902b38b7..a4620cfe1 100644
--- a/odata-url-conventions/4 Resource Path.md
+++ b/odata-url-conventions/4 Resource Path.md
@@ -679,8 +679,8 @@ complex type instance can be appended with a type-cast segment containing the
qualified name of a type derived from the declared type of the
identified resource. If used in a resource path and the identified
resource is not an instance of the derived type, the request will result
-in a `404 Not Found` response. If used in a path expression that is part
-of a Boolean expression, the type cast will evaluate to `null`.
+in a `404 Not Found` response. If used in a path expression,
+the type cast will evaluate to `null`.
Services MAY additionally support the use of the unqualified name of a
derived type in a URL by defining one or more default namespaces through
From a254a86ed6ac2bfadb873efadd6212844741992f Mon Sep 17 00:00:00 2001
From: Ralf Handl
Date: Wed, 29 Nov 2023 18:19:26 +0100
Subject: [PATCH 14/22] ODATA-1587: Remove reference to obsolete GeoJSON
document (#194)
---
docs/odata-json-format/odata-json-format.html | 8 +-------
docs/odata-json-format/odata-json-format.md | 14 +-------------
odata-json-format/7 Structural Property.md | 10 +---------
odata-json-format/Appendix.md | 4 ----
4 files changed, 3 insertions(+), 33 deletions(-)
diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html
index 2336c1fb6..9b4381f99 100644
--- a/docs/odata-json-format/odata-json-format.html
+++ b/docs/odata-json-format/odata-json-format.html
@@ -743,11 +743,7 @@ 7.1
Values of type Edm.Binary
, Edm.Date
, Edm.DateTimeOffset
, Edm.Duration
, Edm.Guid
, and Edm.TimeOfDay
are represented as JSON strings whose content satisfies the rules binaryValue
, dateValue
, dateTimeOffsetValue
, durationValue
, guidValue
, and timeOfDayValue
respectively, in OData-ABNF.
Primitive values that cannot be represented, for example due to server conversion issues or IEEE754 limitations on the size of an Edm.Int64
or Edm.Decimal
value, are annotated with the Core.ValueException
term. In this case, the payload MAY include an approximation of the value and MAY specify a string representation of the exact value in the value
property of the annotation.
Enumeration values are represented as JSON strings whose content satisfies the rule enumValue
in OData-ABNF. The preferred representation is the enumerationMember
. If no enumerationMember
(or combination of named enumeration members) is available, the enumMemberValue
representation may be used.
-Geography and geometry values are represented as geometry types as defined in RFC7946, with the following modifications:
-
-- Keys SHOULD be ordered with type first, then coordinates, then any other keys
-- If the optional CRS object is present, it MUST be of type
name
, where the value of the name
member of the contained properties
object is an EPSG SRID legacy identifier, see [GeoJSON-2008].
-
+Geography and geometry values are represented as geometry types as defined in RFC7946.
Geography and geometry types have the same representation in a JSON payload. Whether the value represents a geography type or geometry type is inferred from its usage or specified using the type
control information.
Example 12:
@@ -2017,8 +2013,6 @@ [RFC8259]
A.2 Informative References
[ECMAScript]
ECMAScript 2023 Language Specification, 14th Edition, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
-[GeoJSON-2008]
-Butler, H., Daly, M., Doyle, A., Gillies, S., Schaub, T., and C. Schmidt, “The GeoJSON Format Specification”, June 2008 http://geojson.org/geojson-spec.html.
Appendix B. Safety, Security and Privacy Considerations
This specification raises no security issues.
diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md
index bcf80d345..e1dd4ebbc 100644
--- a/docs/odata-json-format/odata-json-format.md
+++ b/docs/odata-json-format/odata-json-format.md
@@ -1388,15 +1388,7 @@ combination of named enumeration members) is
available, the `enumMemberValue` representation may be used.
Geography and geometry values are represented as geometry types as
-defined in [RFC7946](#rfc7946), with the following
-modifications:
-
-- Keys SHOULD be ordered with type first, then coordinates, then any other keys
-- If the optional [CRS
- object](http://geojson.org/geojson-spec.html#named-crs) is present, it
- MUST be of type `name`, where the value of the
- `name` member of the contained `properties` object
- is an EPSG SRID legacy identifier, see [[GeoJSON-2008](#GeoJSON-2008)].
+defined in [RFC7946](#rfc7946).
Geography and geometry types have the same representation in a JSON
payload. Whether the value represents a geography type or geometry type
@@ -3790,10 +3782,6 @@ https://www.rfc-editor.org/info/rfc8259.
###### [ECMAScript]
_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
-###### [GeoJSON-2008]
-_Butler, H., Daly, M., Doyle, A., Gillies, S., Schaub, T., and C. Schmidt, "The GeoJSON Format Specification", June 2008_
-http://geojson.org/geojson-spec.html.
-
-------
# Appendix B. Safety, Security and Privacy Considerations
diff --git a/odata-json-format/7 Structural Property.md b/odata-json-format/7 Structural Property.md
index b98aae8cf..d7b56f083 100644
--- a/odata-json-format/7 Structural Property.md
+++ b/odata-json-format/7 Structural Property.md
@@ -54,15 +54,7 @@ combination of named enumeration members) is
available, the `enumMemberValue` representation may be used.
Geography and geometry values are represented as geometry types as
-defined in [RFC7946](#rfc7946), with the following
-modifications:
-
-- Keys SHOULD be ordered with type first, then coordinates, then any other keys
-- If the optional [CRS
- object](http://geojson.org/geojson-spec.html#named-crs) is present, it
- MUST be of type `name`, where the value of the
- `name` member of the contained `properties` object
- is an EPSG SRID legacy identifier, see [[GeoJSON-2008](#GeoJSON-2008)].
+defined in [RFC7946](#rfc7946).
Geography and geometry types have the same representation in a JSON
payload. Whether the value represents a geography type or geometry type
diff --git a/odata-json-format/Appendix.md b/odata-json-format/Appendix.md
index 6aea417d2..6d50ee3a9 100644
--- a/odata-json-format/Appendix.md
+++ b/odata-json-format/Appendix.md
@@ -80,10 +80,6 @@ https://www.rfc-editor.org/info/rfc8259.
_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262.
https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
-###### [GeoJSON-2008]
-_Butler, H., Daly, M., Doyle, A., Gillies, S., Schaub, T., and C. Schmidt, "The GeoJSON Format Specification", June 2008_
-http://geojson.org/geojson-spec.html.
-
-------
# Appendix ##asec Safety, Security and Privacy Considerations
From 153def271909c3b2b36c093b31cd2bf1c7d87950 Mon Sep 17 00:00:00 2001
From: Ralf Handl
Date: Wed, 29 Nov 2023 18:29:52 +0100
Subject: [PATCH 15/22] ODATA-1593 (#197)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Heiko Theißen
---
docs/odata-json-format/odata-json-format.html | 855 ++++++++++--------
docs/odata-json-format/odata-json-format.md | 156 +++-
docs/odata-protocol/odata-protocol.html | 8 +-
docs/odata-protocol/odata-protocol.md | 12 +-
odata-json-format/15 Delta Payload.md | 156 +++-
odata-protocol/11.4 Data Modification.md | 8 +-
odata-protocol/8 Header Fields.md | 4 +-
7 files changed, 819 insertions(+), 380 deletions(-)
diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html
index 9b4381f99..7fb143ed8 100644
--- a/docs/odata-json-format/odata-json-format.html
+++ b/docs/odata-json-format/odata-json-format.html
@@ -1301,9 +1301,9 @@ 15.5 Deleted
target
— The id of the related entity for multi-valued navigation properties, which may be absolute or relative. For delta payloads that do not specify an OData-Version
header value of 4.0
, the target MAY be omitted for single-valued navigation.
15.6 Update a Collection of Entities
-The body of a PATCH request to a URL identifying a collection of entities is a JSON object. It MUST contain the context
control information with a string value of #$delta
, and it MUST contain an array-valued property named value
containing all added, changed, or deleted entities, as well as added or deleted links between entities.
+The body of a PATCH
request to a URL identifying a collection of entities is a JSON object. It MUST contain the context
control information with a string value of #$delta
, and it MUST contain an array-valued property named value
containing all added, changed, or deleted entities, as well as added or deleted links between entities.
-Example 39: 4.01 delta response customers with expanded orders represented inline as a delta
+Example 39: 4.01 collection-update request for customers with expanded orders represented inline as a delta
- Add customer
EASTC
- Change
ContactName
of customer AROUT
@@ -1312,69 +1312,212 @@
- Create order 11011
- Add link to existing order 10692
-- Change
ShippedDate
of related order 10835
+- Change
RequiredDate
of related order 10835
- Delete link to order 10643
Add link between customer ANATR
and order 10643
Delete link between customer DUMON
and order 10311
-{
-"@context": "#$delta",
- "value": [
- {
- "CustomerID": "EASTC",
- "CompanyName": "Eastern Connection",
- "ContactName": "Ann Devon",
- "ContactTitle": "Sales Agent"
- },
+ PATCH /service/Customers HTTP/1.1
+Host: host
+Content-Type: application/json
+Content-Length: ###
+Prefer: return=minimal, continue-on-error
+
+{
+"@context": "#$delta",
+ "value": [
{
- "CustomerID": "AROUT",
- "ContactName": "Thomas Hardy",
- },
- {
- "@removed": {},
- "CustomerID":"ANTON"
- },
- {
- "CustomerID": "ALFKI",
- "Orders@delta": [
- {
- "OrderID": 11011,
- "CustomerID": "ALFKI",
- "EmployeeID": 3,
- "OrderDate": "1998-04-09T00:00:00Z",
- "RequiredDate": "1998-05-07T00:00:00Z",
- "ShippedDate": "1998-04-13T00:00:00Z"
- },
- {
- "@id": "Orders(10692)"
- },
- {
- "@id": "Orders(10835)",
- "ShippedDate": "1998-01-23T00:00:00Z",
- },
- {
- "@removed": {
- "reason": "changed"
- },
- "OrderID": 10643
- }
- ]
- },
- {
- "@context": "#Customers/$link",
- "source": "Customers('ANATR')",
- "relationship":" Orders",
- "target": "Orders(10643)"
- },
- {
- "@context": "#Customers/$deletedLink",
- "source": "Customers('DUMON')",
- "relationship": "Orders",
- "target": "Orders(10311)"
- }
- ]
- }
+"@Org.OData.Core.V1.ContentID": "1",
+ "CustomerID": "EASTC",
+ "CompanyName": "Eastern Connection",
+ "ContactName": "Ann Devon",
+ "ContactTitle": "Sales Agent"
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "2",
+ "CustomerID": "AROUT",
+ "ContactName": "Thomas Hardy",
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "3",
+ "@removed": {},
+ "CustomerID":"ANTON"
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "4",
+ "CustomerID": "ALFKI",
+ "Orders@delta": [
+ {
+ "@Org.OData.Core.V1.ContentID": "4.1",
+ "OrderID": 11011,
+ "CustomerID": "ALFKI",
+ "EmployeeID": 3,
+ "OrderDate": "1998-04-09T00:00:00Z",
+ "RequiredDate": "1998-05-07T00:00:00Z",
+ "ShippedDate": "1998-04-13T00:00:00Z"
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "4.2",
+ "@id": "Orders(10692)"
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "4.3",
+ "@id": "Orders(10835)",
+ "RequiredDate": "1998-01-23T00:00:00Z",
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "4.4",
+ "@removed": {
+ "reason": "changed"
+ },
+ "OrderID": 10643
+ }
+ ]
+ },
+ {
+ "@context": "#Customers/$link",
+ "@Org.OData.Core.V1.ContentID": "5",
+ "source": "Customers('ANATR')",
+ "relationship":" Orders",
+ "target": "Orders(10643)"
+ },
+ {
+ "@context": "#Customers/$deletedLink",
+ "@Org.OData.Core.V1.ContentID": "6",
+ "source": "Customers('DUMON')",
+ "relationship": "Orders",
+ "target": "Orders(10311)"
+ }
+ ]
+ }
+Assuming all changes can be applied without errors, the response would be
+HTTP/1.1 204 No Content
+Preference-Applied: return=minimal, continue-on-error
+
+
+Assuming some or all changes cannot be applied, the overall request is still deemed successful due to the continue-on-error
preference, and the response details what went wrong
+
+- Add customer ‘EASTC’ - failed
+- Change
ContactName
of customer ‘AROUT’ - failed
+- Delete customer ‘ANTON’ - failed
+- Change customer ‘ALFKI’:
+
+- Create order 11011 - succeeded, not mentioned in response
+- Add link to existing order 10692 - succeeded, not mentioned in response
+- Change
RequiredDate
of related order 10835 - failed
+- Delete link to order 10643 - succeeded, not mentioned in response
+
+- Add link between customer ‘ANATR’ and order 10643 - failed without further info
+- Delete link between customer ‘DUMON’ and order 10311 - failed without further info
+
+HTTP/1.1 200 OK
+Content-Type: application/json
+Content-Length: ###
+Preference-Applied: return=minimal, continue-on-error
+
+{
+"@context": "#$delta",
+ "value": [
+ {
+ "@Org.OData.Core.V1.ContentID": "1",
+ "CustomerID": "EASTC",
+ "@removed": {},
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "insert",
+ "responseCode": 400,
+ "info": {
+ "code": "incmplt",
+ "message": "Required field(s) not provided",
+ "target": "Address",
+ "@OtherVocab.additionalTargets": [ "Industry", "VATRegistration" ],
+ "severity": "error"
+ }
+ }
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "2",
+ "CustomerID": "AROUT",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "update",
+ "responseCode": 400,
+ "info": {
+ "code": "r-o",
+ "message": "Customer is archived and cannot be changed",
+ "severity": "error"
+ }
+ }
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "3",
+ "CustomerID":"ANTON"
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "delete",
+ "responseCode": 400,
+ "info": {
+ "code": "ufo",
+ "message": "Customer has unfinished orders and cannot be deleted",
+ "severity": "error"
+ }
+ }
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "4",
+ "CustomerID": "ALFKI",
+ "Orders@delta": [
+ {
+ "@Org.OData.Core.V1.ContentID": "4.3",
+ "@id": "Orders(10835)",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "update",
+ "responseCode": 400,
+ "info": {
+ "code": "b/s",
+ "message": "RequiredDate cannot be changed because Order is already being shipped",
+ "severity": "error"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "@context": "#Customers/$deletedLink",
+ "@Org.OData.Core.V1.ContentID": "5",
+ "source": "Customers('ANATR')",
+ "relationship":" Orders",
+ "target": "Orders(10643)",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "link",
+ "responseCode": 404,
+ "info": null
+ }
+ },
+ {
+ "@context": "#Customers/$link",
+ "@Org.OData.Core.V1.ContentID": "6",
+ "source": "Customers('DUMON')",
+ "relationship": "Orders",
+ "target": "Orders(10311)",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "unlink",
+ "responseCode": 400
+ }
+ }
+ ]
+ }
+Without the continue-on-error
preference processing would stop on the first error, and the response would be a standard OData error response
+HTTP/1.1 400 Bad Request
+Content-Type: application/json
+Content-Length: ###
+
+{
+"error": {
+ "code": "incmplt",
+ "message": "Required field(s) not provided",
+ "target": "Customers('EASTC')/Address",
+ "@OtherVocab.additionalTargets": [ "Customers('EASTC')/Industry", "Customers('EASTC')/VATRegistration" ]
+ }
+ }
16 Bound Function
@@ -1388,46 +1531,46 @@ 16 Boun
If metadata=minimal
is requested, the target
name/value pair MUST be included if its value differs from the canonical function or action URL.
Example 40: minimal representation of a function where all overloads are applicable
-{
-"@context": "http://host/service/$metadata#Employees/$entity",
- "#Model.RemainingVacation": {},
- ...
- }
+{
+"@context": "http://host/service/$metadata#Employees/$entity",
+ "#Model.RemainingVacation": {},
+ ...
+ }
Example 41: full representation of a specific overload with parameter alias for the Year
parameter
-{
-"@context": "http://host/service/$metadata#Employees/$entity",
- "#Model.RemainingVacation(Year)": {
- "title": "Remaining vacation from year.",
- "target": "Employees(2)/RemainingVacation(Year=@Year)"
- },
- ...
- }
+{
+"@context": "http://host/service/$metadata#Employees/$entity",
+ "#Model.RemainingVacation(Year)": {
+ "title": "Remaining vacation from year.",
+ "target": "Employees(2)/RemainingVacation(Year=@Year)"
+ },
+ ...
+ }
Example 42: full representation in a collection
-{
-"@context": "http://host/service/$metadata#Employees",
- "#Model.RemainingVacation": {
- "title": "Remaining Vacation",
- "target": "Managers(22)/Employees/RemainingVacation"
- },
- "value": [ ... ]
- }
+{
+"@context": "http://host/service/$metadata#Employees",
+ "#Model.RemainingVacation": {
+ "title": "Remaining Vacation",
+ "target": "Managers(22)/Employees/RemainingVacation"
+ },
+ "value": [ ... ]
+ }
Example 43: full representation in a nested collection
-{
-"@context": "http://host/service/$metadata#Employees/$entity",
- "@type": "Model.Manager",
- "ID":22,
- ...
- "Employees#RemainingVacation": {
- "title": "RemainingVacation",
- "target": "Managers(22)/Employees/RemainingVacation"
- }
- }
+{
+"@context": "http://host/service/$metadata#Employees/$entity",
+ "@type": "Model.Manager",
+ "ID":22,
+ ...
+ "Employees#RemainingVacation": {
+ "title": "RemainingVacation",
+ "target": "Managers(22)/Employees/RemainingVacation"
+ }
+ }
17 Bound Action
@@ -1441,46 +1584,46 @@ 17 Bound Acti
If metadata=minimal
is requested, the target
name/value pair MUST be included if its value differs from the canonical function or action URL.
Example 44: minimal representation in an entity
-{
-"@context": "http://host/service/$metadata#LeaveRequests/$entity",
- "#Model.Approve": {},
- ...
- }
+{
+"@context": "http://host/service/$metadata#LeaveRequests/$entity",
+ "#Model.Approve": {},
+ ...
+ }
Example 45: full representation in an entity:
-{
-"@context": "http://host/service/$metadata#LeaveRequests/$entity",
- "#Model.Approve": {
- "title": "Approve Leave Request",
- "target": "LeaveRequests(2)/Approve"
- },
- ...
- }
+{
+"@context": "http://host/service/$metadata#LeaveRequests/$entity",
+ "#Model.Approve": {
+ "title": "Approve Leave Request",
+ "target": "LeaveRequests(2)/Approve"
+ },
+ ...
+ }
Example 46: full representation in a collection
-{
-"@context": "http://host/service/$metadata#LeaveRequests",
- "#Model.Approve": {
- "title": "Approve All Leave Requests",
- "target": "Employees(22)/Model.Manager/LeaveRequests/Approve"
- },
- "value": [ ... ]
- }
+{
+"@context": "http://host/service/$metadata#LeaveRequests",
+ "#Model.Approve": {
+ "title": "Approve All Leave Requests",
+ "target": "Employees(22)/Model.Manager/LeaveRequests/Approve"
+ },
+ "value": [ ... ]
+ }
Example 47: full representation in a nested collection
-{
-"@context": "http://host/service/$metadata#Employees/$entity",
- "@type": "Model.Manager",
- "ID": 22,
- ...
- "LeaveRequests#Model.Approve": {
- "title": "Approve All Leave Requests",
- "target": "Employees(22)/Model.Manager/LeaveRequests/Approve"
- }
- }
+{
+"@context": "http://host/service/$metadata#Employees/$entity",
+ "@type": "Model.Manager",
+ "ID": 22,
+ ...
+ "LeaveRequests#Model.Approve": {
+ "title": "Approve All Leave Requests",
+ "target": "Employees(22)/Model.Manager/LeaveRequests/Approve"
+ }
+ }
18 Action Invocation
@@ -1489,15 +1632,15 @@ Core.OptionalParameter
defined in OData-VocCore MAY be omitted from the request body. If an omitted parameter is not annotated (and thus nullable), it MUST be interpreted as having the null
value. If it is annotated and the annotation specifies a DefaultValue
, the omitted parameter is interpreted as having that default value. If omitted and the annotation does not specify a default value, the service is free on how to interpret the omitted parameter. Note: a nullable non-binding parameter is equivalent to being annotated as optional with a default value of null
.
Example 46:
-{
-"param1": 42,
- "param2": {
- "Street": "One Microsoft Way",
- "Zip": 98052
- },
- "param3": [ 1, 42, 99 ],
- "param4": null
- }
+{
+"param1": 42,
+ "param2": {
+ "Street": "One Microsoft Way",
+ "Zip": 98052
+ },
+ "param3": [ 1, 42, 99 ],
+ "param4": null
+ }
In order to invoke an action with no non-binding parameters, the client passes an empty JSON object in the body of the request. 4.01 Services MUST also support clients passing an empty request body for this case.
@@ -1541,45 +1684,45 @@ 19.1 Batc
A second query request
Note: For brevity, in the example, request bodies are excluded in favor of English descriptions inside <>
brackets and OData-Version
headers are omitted.
-POST /service/$batch HTTP/1.1
-Host: host
-OData-Version: 4.01
-Content-Type: application/json
-Content-Length: ###
-
-{
-"requests": [
- {
- "id": "0",
- "method": "get",
- "url": "/service/Customers('ALFKI')"
- },
- {
- "id": "1",
- "atomicityGroup": "group1",
- "dependsOn": [ "0" ],
- "method": "patch",
- "url": "/service/Customers('ALFKI')",
- "headers": {
- "Prefer": "return=minimal"
- },
- "body": <JSON representation of changes to Customer ALFKI>
- },
- {
- "id": "2",
- "atomicityGroup": "group1",
- "method": "post",
- "url": "/service/Customers",
- "body": <JSON representation of a new Customer entity>
- },
- {
- "id": "3",
- "dependsOn": [ "group1" ],
- "method": "get",
- "url": "/service/Products"
- }
- ]
- }
+POST /service/$batch HTTP/1.1
+Host: host
+OData-Version: 4.01
+Content-Type: application/json
+Content-Length: ###
+
+{
+"requests": [
+ {
+ "id": "0",
+ "method": "get",
+ "url": "/service/Customers('ALFKI')"
+ },
+ {
+ "id": "1",
+ "atomicityGroup": "group1",
+ "dependsOn": [ "0" ],
+ "method": "patch",
+ "url": "/service/Customers('ALFKI')",
+ "headers": {
+ "Prefer": "return=minimal"
+ },
+ "body": <JSON representation of changes to Customer ALFKI>
+ },
+ {
+ "id": "2",
+ "atomicityGroup": "group1",
+ "method": "post",
+ "url": "/service/Customers",
+ "body": <JSON representation of a new Customer entity>
+ },
+ {
+ "id": "3",
+ "dependsOn": [ "group1" ],
+ "method": "get",
+ "url": "/service/Products"
+ }
+ ]
+ }
19.2 Referencing New Entities
The entity returned by a preceding request can be referenced in the request URL of subsequent requests. If the Location
header in the response contains a relative URL, clients MUST be able to resolve it relative to the request’s URL even if that contains such a reference.
@@ -1589,29 +1732,29 @@ POST /service/$batch HTTP/1.1
-Host: host
-OData-Version: 4.01
-Content-Type: application/json
-Content-Length: ###
-
-{
-"requests": [
- {
- "id": "1",
- "method": "post",
- "url": "/service/Customers",
- "body": <JSON representation of a new Customer entity>
- },
- {
- "id": "2",
- "dependsOn": [ "1" ]
- "method": "post",
- "url": "$1/Orders",
- "body": <JSON representation of a new Order>
- }
- ]
- }
+POST /service/$batch HTTP/1.1
+Host: host
+OData-Version: 4.01
+Content-Type: application/json
+Content-Length: ###
+
+{
+"requests": [
+ {
+ "id": "1",
+ "method": "post",
+ "url": "/service/Customers",
+ "body": <JSON representation of a new Customer entity>
+ },
+ {
+ "id": "2",
+ "dependsOn": [ "1" ]
+ "method": "post",
+ "url": "$1/Orders",
+ "body": <JSON representation of a new Order>
+ }
+ ]
+ }
19.3 Referencing an ETag
+POST /service/$batch HTTP/1.1
+Host: host
+OData-Version: 4.01
+Content-Type: application/json
+Content-Length: ###
+
+{
+"requests": [
+ {
+ "id": "1",
+ "method": "get",
+ "url": "/service/Employees(0)",
+ "headers": {
+ "accept": "application/json"
+ }
+ },
+ {
+ "id": "2",
+ "dependsOn": [ "1" ],
+ "method": "patch",
+ "url": "/service/Employees(0)",
+ "headers": {
+ "if-match": "$1"
+ },
+ "body": {
+ "Salary": 75000
+ }
+ }
+ ]
+ }
19.4 Processing a Batch Request
All requests in an atomicity group represent a single change unit. A service MUST successfully process and apply all the requests in the atomicity group or else apply none of them. It is up to the service implementation to define rollback semantics to undo any requests within an atomicity group that may have been applied before another request in that same atomicity group failed.
@@ -1669,119 +1812,119 @@ 19.5 B
Relative URLs in a response object follow the rules for relative URLs based on the request URL of the corresponding request. Especially: URLs in responses MUST NOT contain $
-prefixed request identifiers.
Example 51: referencing the batch request example 48 above, assume all the requests except the final query request succeed. In this case the response would be
-HTTP/1.1 200 OK
-OData-Version: 4.01
-Content-Length: ####
-Content-Type: application/json
-
-{
-"responses": [
- {
- "id": "0",
- "status": 200,
- "body": <JSON representation of the Customer entity with key ALFKI>
- },
- {
- "id": "1",
- "status": 204
- },
- {
- "id": "2",
- "status": 201,
- "headers": {
- "location": "http://host/service.svc/Customer('POIUY')"
- },
- "body": <JSON representation of the new Customer entity>
- },
- {
- "id": "3",
- "status": 404,
- "body": <Error message>
- }
- ]
- }
+HTTP/1.1 200 OK
+OData-Version: 4.01
+Content-Length: ####
+Content-Type: application/json
+
+{
+"responses": [
+ {
+ "id": "0",
+ "status": 200,
+ "body": <JSON representation of the Customer entity with key ALFKI>
+ },
+ {
+ "id": "1",
+ "status": 204
+ },
+ {
+ "id": "2",
+ "status": 201,
+ "headers": {
+ "location": "http://host/service.svc/Customer('POIUY')"
+ },
+ "body": <JSON representation of the new Customer entity>
+ },
+ {
+ "id": "3",
+ "status": 404,
+ "body": <Error message>
+ }
+ ]
+ }
19.6 Asynchronous Batch Requests
A batch request that specifies the respond-async
preference MAY be executed asynchronously. This means that the “outer” batch request is executed asynchronously; this preference does not automatically cascade down to the individual requests within the batch. After successful execution of the batch request the response to the batch request is returned in the body of a response to an interrogation request against the status monitor resource URL, see section “Asynchronous Requests” in OData-Protocol.
A service MAY return interim results to an asynchronously executing batch. It does this by responding with 200 OK
to a GET
request to the monitor resource and including a nextLink
control information in the JSON batch response, thus signaling that the response is only a partial result. A subsequent GET
request to the next link MAY result in a 202 Accepted
response with a location
header pointing to a new status monitor resource.
Example 52: referencing the example 47 above again, assume that the request is sent with the respond-async
preference. This results in a 202
response pointing to a status monitor resource:
-HTTP/1.1 202 Accepted
-Location: http://service-root/async-monitor-0
-Retry-After: ###
+HTTP/1.1 202 Accepted
+Location: http://service-root/async-monitor-0
+Retry-After: ###
When interrogating the monitor URL only the first request in the batch has finished processing and all the remaining requests are still being processed. The service signals that asynchronous processing is “finished” and returns a partial result with the first response and a next link. The client did not explicitly accept application/http
, so the response is “unwrapped” and only indicates with the AsyncResult
header that it is a response to a status monitor resource:
-HTTP/1.1 200 OK
-AsyncResult: 200
-OData-Version: 4.01
-Content-Length: ###
-Content-Type: application/json
-
-{
-"responses": [
- {
- "id": "0",
- "status": 200,
- "body": <JSON representation of the Customer entity with key ALFKI>
- }
- ],
- "@nextLink": "...?$skiptoken=YmF0Y2gx"
- }
+HTTP/1.1 200 OK
+AsyncResult: 200
+OData-Version: 4.01
+Content-Length: ###
+Content-Type: application/json
+
+{
+"responses": [
+ {
+ "id": "0",
+ "status": 200,
+ "body": <JSON representation of the Customer entity with key ALFKI>
+ }
+ ],
+ "@nextLink": "...?$skiptoken=YmF0Y2gx"
+ }
Client makes a GET
request to the next link and receives a 202
response with the location of a new monitor resource.
-HTTP/1.1 202 Accepted
-Location: http://service-root/async-monitor-1
-Retry-After: ###
+HTTP/1.1 202 Accepted
+Location: http://service-root/async-monitor-1
+Retry-After: ###
After some time a GET
request to the monitor resource returns the remainder of the result.
-HTTP/1.1 200 OK
-AsyncResult: 200
-OData-Version: 4.01
-Content-Length: ###
-Content-Type: application/json
-
-{
-"responses": [
- {
- "id": "1",
- "status": 204
- },
- {
- "id": "2",
- "status": 201,
- "headers": {
- "location": "http://host/service.svc/Customer('POIUY')"
- },
- "body": <JSON representation of the new Customer entity>
- },
- {
- "id": "3",
- "status": 404,
- "body": <Error message>
- }
- ]
- }
+HTTP/1.1 200 OK
+AsyncResult: 200
+OData-Version: 4.01
+Content-Length: ###
+Content-Type: application/json
+
+{
+"responses": [
+ {
+ "id": "1",
+ "status": 204
+ },
+ {
+ "id": "2",
+ "status": 201,
+ "headers": {
+ "location": "http://host/service.svc/Customer('POIUY')"
+ },
+ "body": <JSON representation of the new Customer entity>
+ },
+ {
+ "id": "3",
+ "status": 404,
+ "body": <Error message>
+ }
+ ]
+ }
In addition to the above interaction pattern individual requests within a batch with no other requests depending on it and not part of an atomicity group MAY be executed asynchronously if they specify the respond-async
preference and if the service responds with a JSON batch response. In this case the response
array contains a response object for each asynchronously executed individual request with a status
of 202
, a location
header pointing to an individual status monitor resource, and optionally a retry-after
header.
Example 53: the first individual request is processed asynchronously, the second synchronously, the batch itself is processed synchronously
-HTTP/1.1 200 OK
-OData-Version: 4.01
-Content-Length: ###
-Content-Type: application/json
-
-{
-"responses": [
- {
- "id": "0",
- "status": 202,
- "headers": {
- "location": "http://service-root/async-monitor-0"
- }
- },
- {
- "id": "1",
- "status": 204
- }
- ]
- }
+HTTP/1.1 200 OK
+OData-Version: 4.01
+Content-Length: ###
+Content-Type: application/json
+
+{
+"responses": [
+ {
+ "id": "0",
+ "status": 202,
+ "headers": {
+ "location": "http://service-root/async-monitor-0"
+ }
+ },
+ {
+ "id": "1",
+ "status": 204
+ }
+ ]
+ }
20 Instance Annotations
@@ -1792,19 +1935,19 @@ single primitive or collection value, the annotations for the value appear next to the value
property and are not prefixed with a property name.
Example 54:
-{
-"@context": "http://host/service/$metadata#Customers",
- "@com.example.customer.setkind": "VIPs",
- "value": [
- {
- "@com.example.display.highlight": true,
- "ID": "ALFKI",
- "CompanyName@com.example.display.style": { "title": true, "order": 1 },
- "CompanyName": "Alfreds Futterkiste",
- "Orders@com.example.display.style#simple": { "order": 2 }
- }
- ]
- }
+{
+"@context": "http://host/service/$metadata#Customers",
+ "@com.example.customer.setkind": "VIPs",
+ "value": [
+ {
+ "@com.example.display.highlight": true,
+ "ID": "ALFKI",
+ "CompanyName@com.example.display.style": { "title": true, "order": 1 },
+ "CompanyName": "Alfreds Futterkiste",
+ "Orders@com.example.display.style#simple": { "order": 2 }
+ }
+ ]
+ }
20.1 Annotate a JSON Object
When annotating a name/value pair for which the value is represented as a JSON object, each annotation is placed within the object and represented as a single name/value pair.
@@ -1832,24 +1975,24 @@ 21.1 E
Error responses MAY contain annotations in any of its JSON objects.
Example 55:
-{
-"error": {
- "code": "err123",
- "message": "Unsupported functionality",
- "target": "query",
- "details": [
- {
- "code": "forty-two",
- "target": "$search",
- "message": "$search query option not supported"
- }
- ],
- "innererror": {
- "trace": [...],
- "context": {...}
- }
- }
- }
+{
+"error": {
+ "code": "err123",
+ "message": "Unsupported functionality",
+ "target": "query",
+ "details": [
+ {
+ "code": "forty-two",
+ "target": "$search",
+ "message": "$search query option not supported"
+ }
+ ],
+ "innererror": {
+ "trace": [...],
+ "context": {...}
+ }
+ }
+ }
21.2 In-Stream Error
In the case that a service encounters an error after sending a success status to the client, the service MUST leave the response malformed. This can be achieved by immediately stopping response serialization and thus omitting (among others) the end-object character of the top-level JSON object in the response.
@@ -1861,9 +2004,9 @@ 21.2
Example 56: note that this is one HTTP header line without any line breaks or optional whitespace
-OData-error: {"code":"err123","message":"Unsupported
-functionality","target":"query","details":[{"code":"forty-two","target":"$search","message":"$search
-query option not supported"}]}
+OData-error: {"code":"err123","message":"Unsupported
+functionality","target":"query","details":[{"code":"forty-two","target":"$search","message":"$search
+query option not supported"}]}
21.3 Error Information in a Success Payload
Services may return error information within a success payload; for example, if the client has specified the continue-on-error
preference.
diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md
index e1dd4ebbc..7ee29c591 100644
--- a/docs/odata-json-format/odata-json-format.md
+++ b/docs/odata-json-format/odata-json-format.md
@@ -2478,7 +2478,7 @@ the target MAY be omitted for single-valued navigation.
## 15.6 Update a Collection of Entities
-The body of a PATCH request to a URL identifying a collection of
+The body of a `PATCH` request to a URL identifying a collection of
entities is a JSON object. It MUST contain the
[`context`](#ControlInformationcontextodatacontext)
control information with a string value of `#$delta`, and it
@@ -2489,7 +2489,7 @@ entities, as well as [added](#AddedLink) or
[deleted](#DeletedLink) links between entities.
::: example
-Example 39: 4.01 delta response customers with expanded orders represented
+Example 39: 4.01 collection-update request for customers with expanded orders represented
inline as a delta
1. Add customer `EASTC`
2. Change `ContactName` of customer `AROUT`
@@ -2497,32 +2497,43 @@ inline as a delta
4. Change customer `ALFKI`:
1. Create order 11011
2. Add link to existing order 10692
- 3. Change `ShippedDate` of related order 10835
+ 3. Change `RequiredDate` of related order 10835
4. Delete link to order 10643
5. Add link between customer `ANATR` and order 10643
6. Delete link between customer `DUMON` and order 10311
```json
+PATCH /service/Customers HTTP/1.1
+Host: host
+Content-Type: application/json
+Content-Length: ###
+Prefer: return=minimal, continue-on-error
+
{
"@context": "#$delta",
"value": [
{
+ "@Org.OData.Core.V1.ContentID": "1",
"CustomerID": "EASTC",
"CompanyName": "Eastern Connection",
"ContactName": "Ann Devon",
"ContactTitle": "Sales Agent"
},
{
+ "@Org.OData.Core.V1.ContentID": "2",
"CustomerID": "AROUT",
"ContactName": "Thomas Hardy",
},
{
+ "@Org.OData.Core.V1.ContentID": "3",
"@removed": {},
"CustomerID":"ANTON"
},
{
+ "@Org.OData.Core.V1.ContentID": "4",
"CustomerID": "ALFKI",
"Orders@delta": [
{
+ "@Org.OData.Core.V1.ContentID": "4.1",
"OrderID": 11011,
"CustomerID": "ALFKI",
"EmployeeID": 3,
@@ -2531,13 +2542,16 @@ inline as a delta
"ShippedDate": "1998-04-13T00:00:00Z"
},
{
+ "@Org.OData.Core.V1.ContentID": "4.2",
"@id": "Orders(10692)"
},
{
+ "@Org.OData.Core.V1.ContentID": "4.3",
"@id": "Orders(10835)",
- "ShippedDate": "1998-01-23T00:00:00Z",
+ "RequiredDate": "1998-01-23T00:00:00Z",
},
{
+ "@Org.OData.Core.V1.ContentID": "4.4",
"@removed": {
"reason": "changed"
},
@@ -2547,12 +2561,14 @@ inline as a delta
},
{
"@context": "#Customers/$link",
+ "@Org.OData.Core.V1.ContentID": "5",
"source": "Customers('ANATR')",
"relationship":" Orders",
"target": "Orders(10643)"
},
{
"@context": "#Customers/$deletedLink",
+ "@Org.OData.Core.V1.ContentID": "6",
"source": "Customers('DUMON')",
"relationship": "Orders",
"target": "Orders(10311)"
@@ -2560,6 +2576,138 @@ inline as a delta
]
}
```
+
+Assuming all changes can be applied without errors, the response would be
+```
+HTTP/1.1 204 No Content
+Preference-Applied: return=minimal, continue-on-error
+
+
+```
+
+Assuming some or all changes cannot be applied, the overall request is still deemed successful due to the `continue-on-error` preference, and the response details what went wrong
+ 1. Add customer 'EASTC' - failed
+ 2. Change `ContactName` of customer 'AROUT' - failed
+ 3. Delete customer 'ANTON' - failed
+ 4. Change customer 'ALFKI':
+ 1. Create order 11011 - succeeded, not mentioned in response
+ 2. Add link to existing order 10692 - succeeded, not mentioned in response
+ 3. Change `RequiredDate` of related order 10835 - failed
+ 4. Delete link to order 10643 - succeeded, not mentioned in response
+ 5. Add link between customer 'ANATR' and order 10643 - failed without further info
+ 6. Delete link between customer 'DUMON' and order 10311 - failed without further info
+```json
+HTTP/1.1 200 OK
+Content-Type: application/json
+Content-Length: ###
+Preference-Applied: return=minimal, continue-on-error
+
+{
+ "@context": "#$delta",
+ "value": [
+ {
+ "@Org.OData.Core.V1.ContentID": "1",
+ "CustomerID": "EASTC",
+ "@removed": {},
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "insert",
+ "responseCode": 400,
+ "info": {
+ "code": "incmplt",
+ "message": "Required field(s) not provided",
+ "target": "Address",
+ "@OtherVocab.additionalTargets": [ "Industry", "VATRegistration" ],
+ "severity": "error"
+ }
+ }
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "2",
+ "CustomerID": "AROUT",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "update",
+ "responseCode": 400,
+ "info": {
+ "code": "r-o",
+ "message": "Customer is archived and cannot be changed",
+ "severity": "error"
+ }
+ }
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "3",
+ "CustomerID":"ANTON"
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "delete",
+ "responseCode": 400,
+ "info": {
+ "code": "ufo",
+ "message": "Customer has unfinished orders and cannot be deleted",
+ "severity": "error"
+ }
+ }
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "4",
+ "CustomerID": "ALFKI",
+ "Orders@delta": [
+ {
+ "@Org.OData.Core.V1.ContentID": "4.3",
+ "@id": "Orders(10835)",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "update",
+ "responseCode": 400,
+ "info": {
+ "code": "b/s",
+ "message": "RequiredDate cannot be changed because Order is already being shipped",
+ "severity": "error"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "@context": "#Customers/$deletedLink",
+ "@Org.OData.Core.V1.ContentID": "5",
+ "source": "Customers('ANATR')",
+ "relationship":" Orders",
+ "target": "Orders(10643)",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "link",
+ "responseCode": 404,
+ "info": null
+ }
+ },
+ {
+ "@context": "#Customers/$link",
+ "@Org.OData.Core.V1.ContentID": "6",
+ "source": "Customers('DUMON')",
+ "relationship": "Orders",
+ "target": "Orders(10311)",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "unlink",
+ "responseCode": 400
+ }
+ }
+ ]
+}
+```
+
+Without the `continue-on-error` preference processing would stop on the first error, and the response would be a standard OData error response
+```json
+HTTP/1.1 400 Bad Request
+Content-Type: application/json
+Content-Length: ###
+
+{
+ "error": {
+ "code": "incmplt",
+ "message": "Required field(s) not provided",
+ "target": "Customers('EASTC')/Address",
+ "@OtherVocab.additionalTargets": [ "Customers('EASTC')/Industry", "Customers('EASTC')/VATRegistration" ]
+ }
+}
+```
:::
diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html
index 2e34909dc..031fe1220 100644
--- a/docs/odata-protocol/odata-protocol.html
+++ b/docs/odata-protocol/odata-protocol.html
@@ -815,7 +815,7 @@ OData-VocCore.
Properties with null or default values MUST be included in delta payloads, if modified.
-The response to a POST operation MUST include any properties not set to their default value, and the response to a PUT/PATCH operation MUST include any properties whose values were changed as part of the operation.
+The response to a POST
operation MUST include any properties not set to their default value, and the response to a PUT
or PATCH
operation MUST include any properties whose values were changed as part of the operation.
The omit-values
preference does not affect a request payload.
8.2.8.7 Preference return=representation
and return=minimal
The return=representation
and return=minimal
preferences are defined in RFC7240.
@@ -1844,8 +1844,8 @@ ]
}
-If the nested collection is represented as a delta annotation on the navigation property, then the collection contains members to be added or changed and MAY include deleted entities for entities that are no longer part of the collection, using the delta payload format. If the deleted entity specifies a reason
as deleted
, then the entity is both removed from the collection and deleted, otherwise it is removed from the collection and only deleted if the relationship is contained. Non-key properties of the deleted entity are ignored. Nested collections MUST NOT contain added or deleted links. If the request contains nested delta collections, then the PATCH verb must be specified.
-If a nested entity has the same id or key fields as an existing entity, the existing entity is updated according to the semantics of the PUT or PATCH request. Nested entities that have no id or key fields, or for which the id or key fields do not match existing entities, are treated as inserts. If the nested collection does not represent a containment relationship and has no navigation property binding, then such entities MUST include a context URL specifying the entity set in which the new entity is to be created. If any nested entities contain both id and key fields, they MUST identify the same entity, or the request is invalid.
+If the nested collection is represented as a delta annotation on the navigation property, then the collection contains members to be added or changed and MAY include deleted entities for entities that are no longer part of the collection, using the delta payload format. If the deleted entity specifies a reason
as deleted
, then the entity is both removed from the collection and deleted, otherwise it is removed from the collection and only deleted if the relationship is contained. Non-key properties of the deleted entity are ignored. Nested collections MUST NOT contain added or deleted links. If the request contains nested delta collections, then the PATCH
verb must be specified.
+If a nested entity has the same id or key fields as an existing entity, the existing entity is updated according to the semantics of the PUT
or PATCH
request. Nested entities that have no id or key fields, or for which the id or key fields do not match existing entities, are treated as inserts. If the nested collection does not represent a containment relationship and has no navigation property binding, then such entities MUST include a context URL specifying the entity set in which the new entity is to be created. If any nested entities contain both id and key fields, they MUST identify the same entity, or the request is invalid.
Example 79: using the JSON format, a 4.01 PATCH
request can specify a nested delta representation to:
@@ -2025,7 +2025,7 @@ Core.ContentID
term defined in OData-VocCore. Services that respond with 200 OK
SHOULD annotate the entities in the response using the same Core.ContentID
value as specified in the request.
Services SHOULD advertise support for updating a collection using a delta payload through the DeltaUpdateSupported
property of the Capabilities.UpdateRestrictions
term, and SHOULD advertise support for returning the Core.ContentID
through the ContentIDSupported
property of the Capabilities.DeepUpdateSupport
term, both defined in OData-VocCap.
The response, if requested, is a delta payload, in the same structure and order as the request payload, representing the applied changes.
-If the continue-on-error
preference has been specified and any errors occur in processing the changes, then a delta response MUST be returned regardless of the return
preference and MUST contain at least the failed changes. The service represents failed changes in the delta response as follows:
+If the continue-on-error
preference has been specified and any errors occur in processing the changes, then a delta response MUST be returned regardless of the return
preference and MUST contain at least the failed changes. The service represents failed changes in the delta response as follows:
- Failed deletes in the request MUST be represented in the response as either entities or entity references, annotated with the term
Core.DataModificationException
, see OData-VocCore. If the deleted entity specified a reason of deleted
, the value of failedOperation
MUST be delete
, otherwise unlink
.
- Failed inserts within the request MUST be represented in the response as deleted entities annotated with the term
Core.DataModificationException
with a failedOperation
value of insert
.
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md
index 109bb298a..ee791abb5 100644
--- a/docs/odata-protocol/odata-protocol.md
+++ b/docs/odata-protocol/odata-protocol.md
@@ -1490,8 +1490,8 @@ permissions and has been replaced with the instance annotation
Properties with null or default values MUST be included in delta
payloads, if modified.
-The response to a POST operation MUST include any properties not set to
-their default value, and the response to a PUT/PATCH operation MUST
+The response to a `POST` operation MUST include any properties not set to
+their default value, and the response to a `PUT` or `PATCH` operation MUST
include any properties whose values were changed as part of the
operation.
@@ -4426,12 +4426,12 @@ the entity is both removed from the collection and deleted, otherwise it
is removed from the collection and only deleted if the relationship is
contained. Non-key properties of the deleted entity are ignored. Nested
collections MUST NOT contain added or deleted links. If the request
-contains nested delta collections, then the PATCH verb must be
+contains nested delta collections, then the `PATCH` verb must be
specified.
If a nested entity has the same id or key fields as an existing entity,
-the existing entity is updated according to the semantics of the PUT or
-PATCH request. Nested entities that have no id or key fields, or for
+the existing entity is updated according to the semantics of the `PUT` or
+`PATCH` request. Nested entities that have no id or key fields, or for
which the id or key fields do not match existing entities, are treated
as inserts. If the nested collection does not represent a containment
relationship and has no navigation property binding, then such entities
@@ -4977,7 +4977,7 @@ term, both defined in [OData-VocCap](#ODataVocCap).
The response, if requested, is a delta payload, in the same structure
and order as the request payload, representing the applied changes.
-If the `continue-on-error` preference has been specified and any errors
+If the [`continue-on-error`](#Preferencecontinueonerrorodatacontinueonerror) preference has been specified and any errors
occur in processing the changes, then a delta response MUST be returned
regardless of the [`return`](#Preferencereturnrepresentationandreturnminimal)
preference and MUST contain at least the failed changes. The service
diff --git a/odata-json-format/15 Delta Payload.md b/odata-json-format/15 Delta Payload.md
index f7241623a..db7df27af 100644
--- a/odata-json-format/15 Delta Payload.md
+++ b/odata-json-format/15 Delta Payload.md
@@ -409,7 +409,7 @@ the target MAY be omitted for single-valued navigation.
## ##subsec Update a Collection of Entities
-The body of a PATCH request to a URL identifying a collection of
+The body of a `PATCH` request to a URL identifying a collection of
entities is a JSON object. It MUST contain the
[`context`](#ControlInformationcontextodatacontext)
control information with a string value of `#$delta`, and it
@@ -420,7 +420,7 @@ entities, as well as [added](#AddedLink) or
[deleted](#DeletedLink) links between entities.
::: example
-Example ##ex: 4.01 delta response customers with expanded orders represented
+Example ##ex: 4.01 collection-update request for customers with expanded orders represented
inline as a delta
1. Add customer `EASTC`
2. Change `ContactName` of customer `AROUT`
@@ -428,32 +428,43 @@ inline as a delta
4. Change customer `ALFKI`:
1. Create order 11011
2. Add link to existing order 10692
- 3. Change `ShippedDate` of related order 10835
+ 3. Change `RequiredDate` of related order 10835
4. Delete link to order 10643
5. Add link between customer `ANATR` and order 10643
6. Delete link between customer `DUMON` and order 10311
```json
+PATCH /service/Customers HTTP/1.1
+Host: host
+Content-Type: application/json
+Content-Length: ###
+Prefer: return=minimal, continue-on-error
+
{
"@context": "#$delta",
"value": [
{
+ "@Org.OData.Core.V1.ContentID": "1",
"CustomerID": "EASTC",
"CompanyName": "Eastern Connection",
"ContactName": "Ann Devon",
"ContactTitle": "Sales Agent"
},
{
+ "@Org.OData.Core.V1.ContentID": "2",
"CustomerID": "AROUT",
"ContactName": "Thomas Hardy",
},
{
+ "@Org.OData.Core.V1.ContentID": "3",
"@removed": {},
"CustomerID":"ANTON"
},
{
+ "@Org.OData.Core.V1.ContentID": "4",
"CustomerID": "ALFKI",
"Orders@delta": [
{
+ "@Org.OData.Core.V1.ContentID": "4.1",
"OrderID": 11011,
"CustomerID": "ALFKI",
"EmployeeID": 3,
@@ -462,13 +473,16 @@ inline as a delta
"ShippedDate": "1998-04-13T00:00:00Z"
},
{
+ "@Org.OData.Core.V1.ContentID": "4.2",
"@id": "Orders(10692)"
},
{
+ "@Org.OData.Core.V1.ContentID": "4.3",
"@id": "Orders(10835)",
- "ShippedDate": "1998-01-23T00:00:00Z",
+ "RequiredDate": "1998-01-23T00:00:00Z",
},
{
+ "@Org.OData.Core.V1.ContentID": "4.4",
"@removed": {
"reason": "changed"
},
@@ -478,12 +492,14 @@ inline as a delta
},
{
"@context": "#Customers/$link",
+ "@Org.OData.Core.V1.ContentID": "5",
"source": "Customers('ANATR')",
"relationship":" Orders",
"target": "Orders(10643)"
},
{
"@context": "#Customers/$deletedLink",
+ "@Org.OData.Core.V1.ContentID": "6",
"source": "Customers('DUMON')",
"relationship": "Orders",
"target": "Orders(10311)"
@@ -491,4 +507,136 @@ inline as a delta
]
}
```
+
+Assuming all changes can be applied without errors, the response would be
+```
+HTTP/1.1 204 No Content
+Preference-Applied: return=minimal, continue-on-error
+
+
+```
+
+Assuming some or all changes cannot be applied, the overall request is still deemed successful due to the `continue-on-error` preference, and the response details what went wrong
+ 1. Add customer 'EASTC' - failed
+ 2. Change `ContactName` of customer 'AROUT' - failed
+ 3. Delete customer 'ANTON' - failed
+ 4. Change customer 'ALFKI':
+ 1. Create order 11011 - succeeded, not mentioned in response
+ 2. Add link to existing order 10692 - succeeded, not mentioned in response
+ 3. Change `RequiredDate` of related order 10835 - failed
+ 4. Delete link to order 10643 - succeeded, not mentioned in response
+ 5. Add link between customer 'ANATR' and order 10643 - failed without further info
+ 6. Delete link between customer 'DUMON' and order 10311 - failed without further info
+```json
+HTTP/1.1 200 OK
+Content-Type: application/json
+Content-Length: ###
+Preference-Applied: return=minimal, continue-on-error
+
+{
+ "@context": "#$delta",
+ "value": [
+ {
+ "@Org.OData.Core.V1.ContentID": "1",
+ "CustomerID": "EASTC",
+ "@removed": {},
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "insert",
+ "responseCode": 400,
+ "info": {
+ "code": "incmplt",
+ "message": "Required field(s) not provided",
+ "target": "Address",
+ "@OtherVocab.additionalTargets": [ "Industry", "VATRegistration" ],
+ "severity": "error"
+ }
+ }
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "2",
+ "CustomerID": "AROUT",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "update",
+ "responseCode": 400,
+ "info": {
+ "code": "r-o",
+ "message": "Customer is archived and cannot be changed",
+ "severity": "error"
+ }
+ }
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "3",
+ "CustomerID":"ANTON"
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "delete",
+ "responseCode": 400,
+ "info": {
+ "code": "ufo",
+ "message": "Customer has unfinished orders and cannot be deleted",
+ "severity": "error"
+ }
+ }
+ },
+ {
+ "@Org.OData.Core.V1.ContentID": "4",
+ "CustomerID": "ALFKI",
+ "Orders@delta": [
+ {
+ "@Org.OData.Core.V1.ContentID": "4.3",
+ "@id": "Orders(10835)",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "update",
+ "responseCode": 400,
+ "info": {
+ "code": "b/s",
+ "message": "RequiredDate cannot be changed because Order is already being shipped",
+ "severity": "error"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "@context": "#Customers/$deletedLink",
+ "@Org.OData.Core.V1.ContentID": "5",
+ "source": "Customers('ANATR')",
+ "relationship":" Orders",
+ "target": "Orders(10643)",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "link",
+ "responseCode": 404,
+ "info": null
+ }
+ },
+ {
+ "@context": "#Customers/$link",
+ "@Org.OData.Core.V1.ContentID": "6",
+ "source": "Customers('DUMON')",
+ "relationship": "Orders",
+ "target": "Orders(10311)",
+ "@Org.OData.Core.V1.DataModificationException": {
+ "failedOperation": "unlink",
+ "responseCode": 400
+ }
+ }
+ ]
+}
+```
+
+Without the `continue-on-error` preference processing would stop on the first error, and the response would be a standard OData error response
+```json
+HTTP/1.1 400 Bad Request
+Content-Type: application/json
+Content-Length: ###
+
+{
+ "error": {
+ "code": "incmplt",
+ "message": "Required field(s) not provided",
+ "target": "Customers('EASTC')/Address",
+ "@OtherVocab.additionalTargets": [ "Customers('EASTC')/Industry", "Customers('EASTC')/VATRegistration" ]
+ }
+}
+```
:::
diff --git a/odata-protocol/11.4 Data Modification.md b/odata-protocol/11.4 Data Modification.md
index 4314a5d43..bf5f0a861 100644
--- a/odata-protocol/11.4 Data Modification.md
+++ b/odata-protocol/11.4 Data Modification.md
@@ -457,12 +457,12 @@ the entity is both removed from the collection and deleted, otherwise it
is removed from the collection and only deleted if the relationship is
contained. Non-key properties of the deleted entity are ignored. Nested
collections MUST NOT contain added or deleted links. If the request
-contains nested delta collections, then the PATCH verb must be
+contains nested delta collections, then the `PATCH` verb must be
specified.
If a nested entity has the same id or key fields as an existing entity,
-the existing entity is updated according to the semantics of the PUT or
-PATCH request. Nested entities that have no id or key fields, or for
+the existing entity is updated according to the semantics of the `PUT` or
+`PATCH` request. Nested entities that have no id or key fields, or for
which the id or key fields do not match existing entities, are treated
as inserts. If the nested collection does not represent a containment
relationship and has no navigation property binding, then such entities
@@ -1009,7 +1009,7 @@ term, both defined in [OData-VocCap](#ODataVocCap).
The response, if requested, is a delta payload, in the same structure
and order as the request payload, representing the applied changes.
-If the `continue-on-error` preference has been specified and any errors
+If the [`continue-on-error`](#Preferencecontinueonerrorodatacontinueonerror) preference has been specified and any errors
occur in processing the changes, then a delta response MUST be returned
regardless of the [`return`](#Preferencereturnrepresentationandreturnminimal)
preference and MUST contain at least the failed changes. The service
diff --git a/odata-protocol/8 Header Fields.md b/odata-protocol/8 Header Fields.md
index 8817e79d1..12f946af8 100644
--- a/odata-protocol/8 Header Fields.md
+++ b/odata-protocol/8 Header Fields.md
@@ -614,8 +614,8 @@ permissions and has been replaced with the instance annotation
Properties with null or default values MUST be included in delta
payloads, if modified.
-The response to a POST operation MUST include any properties not set to
-their default value, and the response to a PUT/PATCH operation MUST
+The response to a `POST` operation MUST include any properties not set to
+their default value, and the response to a `PUT` or `PATCH` operation MUST
include any properties whose values were changed as part of the
operation.
From 57cd7b1cab3ce21df9f7f412cb277c5b80e42118 Mon Sep 17 00:00:00 2001
From: Ralf Handl
Date: Wed, 29 Nov 2023 18:35:10 +0100
Subject: [PATCH 16/22] ODATA-1595: replace references to RFC723x with RFC9110
(#193)
---
docs/odata-protocol/odata-protocol.html | 55 ++++++++++-----------
docs/odata-protocol/odata-protocol.md | 64 ++++++++++---------------
odata-protocol/1 Introduction.md | 2 +-
odata-protocol/11.5 Operations.md | 2 +-
odata-protocol/8 Header Fields.md | 38 +++++++--------
odata-protocol/Appendix.md | 22 ++-------
6 files changed, 77 insertions(+), 106 deletions(-)
diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html
index 031fe1220..8a42b660c 100644
--- a/docs/odata-protocol/odata-protocol.html
+++ b/docs/odata-protocol/odata-protocol.html
@@ -654,7 +654,7 @@ OData-JSON and MAY support additional formats for both request and response bodies.
7 Formats
-
The client MAY request a particular response format through the Accept
header, as defined in RFC7231, or through the system query option $format
.
+The client MAY request a particular response format through the Accept
header, as defined in RFC9110, or through the system query option $format
.
In the case that both the Accept
header and the $format
system query option are specified on a request, the value specified in the $format
query option MUST be used.
If the service does not support the requested format, it replies with a 406 Not Acceptable
error response.
Services SHOULD advertise their supported formats in the metadata document by annotating their entity container with the term Capabilities.SupportedFormats
, as defined in OData-VocCap, listing all available formats and combinations of supported format parameters.
@@ -672,13 +672,13 @@ OData-JSON for format-specific details about format parameters within the Content-Type
header.
8.1.2 Header Content-Encoding
-
As defined in RFC7231, the Content-Encoding
header field is used as a modifier to the media-type (as indicated in the Content-Type
header). When present, its value indicates what additional content codings have been applied to the entity-body. A service MAY specify a list of acceptable content codings using an annotation with term Capabilities.AcceptableEncodings
, see OData-VocCap.
+As defined in RFC9110, the Content-Encoding
header field is used as a modifier to the media-type (as indicated in the Content-Type
header). When present, its value indicates what additional content codings have been applied to the entity-body. A service MAY specify a list of acceptable content codings using an annotation with term Capabilities.AcceptableEncodings
, see OData-VocCap.
If the Content-Encoding
header is specified on an individual request or response within a batch, then it specifies the encoding for that individual request or response. Individual requests or responses that don’t include the Content-Encoding
header inherit the encoding of the overall batch request or response.
8.1.3 Header Content-Language
-As defined in RFC7231, a request or response can include a Content-Language
header to indicate the natural language of the intended audience for the enclosed message body. OData does not add any additional requirements over HTTP for including Content-Language
. OData services can annotate model elements whose content depends on the content language with the term Core.IsLanguageDependent
, see OData-VocCore.
+As defined in RFC9110, a request or response can include a Content-Language
header to indicate the natural language of the intended audience for the enclosed message body. OData does not add any additional requirements over HTTP for including Content-Language
. OData services can annotate model elements whose content depends on the content language with the term Core.IsLanguageDependent
, see OData-VocCore.
If the Content-Language
header is specified on an individual request or response within a batch, then it specifies the language for that individual request or response. Individual requests or responses that don’t include the Content-Language
header inherit the language of the overall batch request or response.
8.1.4 Header Content-Length
-As defined in RFC7230, a request or response SHOULD include a Content-Length
header when the message’s length can be determined prior to being transferred. OData does not add any additional requirements over HTTP for writing Content-Length
.
+As defined in RFC9110, a request or response SHOULD include a Content-Length
header when the message’s length can be determined prior to being transferred. OData does not add any additional requirements over HTTP for writing Content-Length
.
If the Content-Length
header is specified on an individual request or response within a batch, then it specifies the length for that individual request or response.
8.1.5 Header OData-Version
OData clients SHOULD use the OData-Version
header on a request to specify the version of the protocol used to generate the request payload.
@@ -690,28 +690,28 @@ 8.2 Request Headers
In addition to the Common Headers, the client may specify any combination of the following request headers.
8.2.1 Header Accept
-As defined in RFC7231, the client MAY specify the set of accepted formats with the Accept
Header.
+As defined in RFC9110, the client MAY specify the set of accepted formats with the Accept
Header.
Services MUST reject formats that specify unknown or unsupported format parameters.
If a media type specified in the Accept
header includes a charset
format parameter and the request also contains an Accept-Charset
header, then the Accept-Charset
header MUST be used.
If the media type specified in the Accept
header does not include a charset
format parameter, then the Content-Type
header of the response MUST NOT contain a charset
format parameter.
The service SHOULD NOT add any format parameters to the Content-Type
header not specified in the Accept
header.
If the Accept
header is specified on an individual request within a batch, then it specifies the acceptable formats for that individual request. Requests within a batch that don’t include the Accept
header inherit the acceptable formats of the overall batch request.
8.2.2 Header Accept-Charset
-As defined in RFC7231, the client MAY specify the set of accepted character sets with the Accept-Charset
header.
+As defined in RFC9110, the client MAY specify the set of accepted character sets with the Accept-Charset
header.
If the Accept-Charset
header is specified on an individual request within a batch, then it specifies the acceptable character sets for that individual request. Requests within a batch that don’t include the Accept-Charset
header inherit the acceptable character sets of the overall batch request.
8.2.3 Header Accept-Language
-As defined in RFC7231, the client MAY specify the set of accepted natural languages with the Accept-Language
header.
+As defined in RFC9110, the client MAY specify the set of accepted natural languages with the Accept-Language
header.
If the Accept-Language
header is specified on an individual request within a batch, then it specifies the acceptable languages for that individual request. Requests within a batch that don’t include the Accept-Language
header inherit the acceptable languages of the overall batch request.
8.2.4 Header If-Match
-As defined in RFC7232, a client MAY include an If-Match
header in a request to GET
, POST
, PUT
, PATCH
or DELETE
. The value of the If-Match
request header MUST be an ETag value previously retrieved for the resource, or *
to match any value.
+As defined in RFC9110, a client MAY include an If-Match
header in a request to GET
, POST
, PUT
, PATCH
or DELETE
. The value of the If-Match
request header MUST be an ETag value previously retrieved for the resource, or *
to match any value.
If an operation on an existing resource requires an ETag, (see term Core.OptimisticConcurrency
in OData-VocCore and property OptimisticConcurrencyControl
of type Capabilities.NavigationPropertyRestriction
in OData-VocCap) and the client does not specify an If-Match
request header in a Data Modification Request or in an Action Request invoking an action bound to the resource, the service responds with a 428 Precondition Required
and MUST ensure that no observable change occurs as a result of the request.
-If present, the request MUST only be processed if the specified ETag value matches the current ETag value of the target resource. Services sending ETag
headers with weak ETags that only depend on the representation-independent entity state MUST use the weak comparison function because it is sufficient to prevent accidental overwrites. This is a deviation from RFC7232.
+If present, the request MUST only be processed if the specified ETag value matches the current ETag value of the target resource. Services sending ETag
headers with weak ETags that only depend on the representation-independent entity state MUST use the weak comparison function because it is sufficient to prevent accidental overwrites. This is a deviation from RFC9110.
If the value does not match the current ETag value of the resource for a Data Modification Request or Action Request, the service MUST respond with 412 Precondition Failed
and MUST ensure that no observable change occurs as a result of the request. In the case of an upsert, if the addressed entity does not exist the provided ETag value is considered not to match.
An If-Match
header with a value of *
in a PUT
or PATCH
request results in an upsert request being processed as an update and not an insert.
The If-Match
header MUST NOT be specified on a batch request, but MAY be specified on individual requests within the batch.
8.2.5 Header If-None-Match
-As defined in RFC7232, a client MAY include an If-None-Match
header in a request to GET
, POST
, PUT
, PATCH
or DELETE
. The value of the If-None-Match
request header MUST be an ETag value previously retrieved for the resource, or *
.
-If present, the request MUST only be processed if the specified ETag value does not match the current ETag value of the resource, using the weak comparison function (see RFC7232). If the value matches the current ETag value of the resource, then for a GET
request, the service SHOULD respond with 304 Not Modified
, and for a Data Modification Request or Action Request, the service MUST respond with 412 Precondition Failed
and MUST ensure that no observable change occurs as a result of the request.
+As defined in RFC9110, a client MAY include an If-None-Match
header in a request to GET
, POST
, PUT
, PATCH
or DELETE
. The value of the If-None-Match
request header MUST be an ETag value previously retrieved for the resource, or *
.
+If present, the request MUST only be processed if the specified ETag value does not match the current ETag value of the resource, using the weak comparison function (see RFC9110). If the value matches the current ETag value of the resource, then for a GET
request, the service SHOULD respond with 304 Not Modified
, and for a Data Modification Request or Action Request, the service MUST respond with 412 Precondition Failed
and MUST ensure that no observable change occurs as a result of the request.
An If-None-Match
header with a value of *
in a PUT
or PATCH
request results in an upsert request being processed as an insert and not an update.
The If-None-Match
header MUST NOT be specified on a batch request, but MAY be specified on individual requests within the batch.
8.2.6 Header Isolation
(OData-Isolation
)
@@ -859,7 +859,7 @@ 200 OK
responses from a status monitor resource in order to indicate the final HTTP Response Status Code of an asynchronously executed request. The header value is the three-digit HTTP response code, see OData-ABNF.
The AsyncResult
header SHOULD NOT be applied to individual responses within a batch.
8.3.2 Header ETag
-A response MAY include an ETag
header, see RFC7232. Services MUST include this header if they require an ETag to be specified when modifying the resource.
+A response MAY include an ETag
header, see RFC9110. Services MUST include this header if they require an ETag to be specified when modifying the resource.
Services MUST support specifying the value returned in the ETag
header in an If-None-Match
header of a subsequent Data Request for the resource. Clients MUST specify the value returned in the ETag
header, or star (*
), in an If-Match
header of a subsequent Data Modification Request or Action Request in order to apply optimistic concurrency control in updating, deleting, or invoking an action bound to the resource.
As OData allows multiple formats for representing the same structured information, services SHOULD use weak ETags that only depend on the representation-independent entity state. A strong ETag MUST change whenever the representation of an entity changes, so it has to depend on the Content-Type
, the Content-Encoding
, and potentially other characteristics of the response.
An ETag
header MAY also be returned on a metadata document request or service document request to allow the client subsequently to make a conditional request for the metadata or service document. Clients can also compare the value of the ETag
header returned from a metadata document request to the metadata ETag returned in a response in order to verify the version of the metadata used to generate that response.
@@ -878,12 +878,12 @@ Prefer
header.
If the Preference-Applied
header is specified on an individual response within a batch, then it specifies the preferences applied to that individual response. If the Preference-Applied
header is specified on a batch response, then it specifies the preferences applied to the overall batch.
8.3.7 Header Retry-After
-A service MAY include a Retry-After
header, as defined in RFC7231, in 202 Accepted
and in 3xx Redirect
responses
+A service MAY include a Retry-After
header, as defined in RFC9110), in 202 Accepted
and in 3xx Redirect
responses
The Retry-After
header specifies the duration of time, in seconds, that the client is asked to wait before retrying the request or issuing a request to the resource returned as the value of the Location
header.
8.3.8 Header Vary
If a response varies depending on the OData-Version
of the response, the service MUST include a Vary
header listing the OData-MaxVersion
request header field to allow correct caching of the response.
If a response varies depending on the applied preferences (allow-entityreferences
, include-annotations
, omit-values
, return
), the service MUST include a Vary
header listing the Prefer
request header field to allow correct caching of the response.
-Alternatively, the server MAY include a Vary
header with the special value *
as defined by RFC7231, Section 8.2.1. Note that this will make it impossible for a proxy to cache the response, see RFC7240.
+Alternatively, the server MAY include a Vary
header with the special value *
as defined by RFC9110, Section 8.2.1. Note that this will make it impossible for a proxy to cache the response, see RFC7240.
9 Common Response Status Codes
An OData service MAY respond to any request using any valid HTTP status code appropriate for the request. A service SHOULD be as specific as possible in its choice of HTTP status codes.
@@ -898,11 +898,11 @@ Data Service Request has been accepted and has not yet completed executing asynchronously. The asynchronous handling of requests is defined in the sections on Asynchronous Requests and Asynchronous Batch Requests.
9.1.4 Response Code 204 No Content
A request returns 204 No Content
if the requested resource has the null
value, or if the service applies a return=minimal
preference. In this case, the response body MUST be empty.
-As defined in RFC7231, a Data Modification Request that responds with 204 No Content
MAY include an ETag
header with a value reflecting the result of the data modification if and only if the client can reasonably “know” the new representation of the resource without actually receiving it. For a PUT
request this means that the response body of a corresponding 200 OK
or 201 Created
response would have been identical to the request body, i.e. no server-side modification of values sent in the request body, no server-calculated values etc. For a PATCH
request this means that the response body of a corresponding 200 OK
or 201 Created
response would have consisted of all values sent in the request body, plus (for values not sent in the request body) server-side values corresponding to the ETag
value sent in the If-Match
header of the PATCH
request, i.e. the previous values “known” to the client.
+As defined in RFC9110, a Data Modification Request that responds with 204 No Content
MAY include an ETag
header with a value reflecting the result of the data modification if and only if the client can reasonably “know” the new representation of the resource without actually receiving it. For a PUT
request this means that the response body of a corresponding 200 OK
or 201 Created
response would have been identical to the request body, i.e. no server-side modification of values sent in the request body, no server-calculated values etc. For a PATCH
request this means that the response body of a corresponding 200 OK
or 201 Created
response would have consisted of all values sent in the request body, plus (for values not sent in the request body) server-side values corresponding to the ETag
value sent in the If-Match
header of the PATCH
request, i.e. the previous values “known” to the client.
9.1.5 Response Code 3xx Redirection
-As per RFC7231, a 3xx Redirection
indicates that further action needs to be taken by the client in order to fulfill the request. In this case, the response SHOULD include a Location
header, as appropriate, with the URL from which the result can be obtained; it MAY include a Retry-After
header.
+As per RFC9110, a 3xx Redirection
indicates that further action needs to be taken by the client in order to fulfill the request. In this case, the response SHOULD include a Location
header, as appropriate, with the URL from which the result can be obtained; it MAY include a Retry-After
header.
9.1.6 Response Code 304 Not Modified
-As per RFC7232, a 304 Not Modified
is returned when the client performs a GET
request containing an If-None-Match
header and the content has not changed. In this case the response SHOULD NOT include other headers in order to prevent inconsistencies between cached entity-bodies and updated headers.
+As per RFC9110, a 304 Not Modified
is returned when the client performs a GET
request containing an If-None-Match
header and the content has not changed. In this case the response SHOULD NOT include other headers in order to prevent inconsistencies between cached entity-bodies and updated headers.
The service MUST ensure that no observable change has occurred to the state of the service as a result of any request that returns a 304 Not Modified
.
9.2 Client Error Responses
Error codes in the 4xx
range indicate a client error, such as a malformed request.
@@ -911,17 +911,17 @@ 9.2.1 Response Code 404 Not Found
404 Not Found
indicates that the resource specified by the request URL does not exist. The response body MAY provide additional information.
9.2.2 Response Code 405 Method Not Allowed
-405 Method Not Allowed
indicates that the resource specified by the request URL does not support the request method. In this case the response MUST include an Allow
header containing a list of valid request methods for the requested resource as defined in RFC7231.
+405 Method Not Allowed
indicates that the resource specified by the request URL does not support the request method. In this case the response MUST include an Allow
header containing a list of valid request methods for the requested resource as defined in RFC9110.
9.2.3 Response Code 406 Not Acceptable
406 Not Acceptable
indicates that the resource specified by the request URL does not have a current representation that would be acceptable for the client according to the request headers Accept
, Accept-Charset
, and Accept-Language
, and that the service is unwilling to supply a default representation.
9.2.4 Response Code 410 Gone
410 Gone
indicates that the requested resource is no longer available. This can happen if a client has waited too long to follow a delta link or a status-monitor-resource link, or a next link on a collection that was requested with snapshot isolation.
9.2.5 Response Code 412 Precondition Failed
-As defined in RFC7232, 412 Precondition Failed
indicates that the client has performed a conditional request and the resource fails the condition. The service MUST ensure that no observable change occurs as a result of the request.
+As defined in RFC9110, 412 Precondition Failed
indicates that the client has performed a conditional request and the resource fails the condition. The service MUST ensure that no observable change occurs as a result of the request.
9.2.6 Response Code 424 Failed Dependency
424 Failed Dependency
indicates that a request was not performed due to a failed dependency; for example, a request within a batch that depended upon a request that failed.
9.3 Server Error Responses
-As defined in RFC7231, error codes in the 5xx
range indicate service errors.
+As defined in RFC9110, error codes in the 5xx
range indicate service errors.
9.3.1 Response Code 501 Not Implemented
If the client requests functionality not implemented by the OData Service, the service responds with 501 Not Implemented
and SHOULD include a response body describing the functionality not implemented.
9.4 Error Response Body
@@ -2222,7 +2222,7 @@ 202 Accepted
response. A service MUST NOT reply to a Data Service Request with 202 Accepted
if the request has not included the respond-async
preference.
Responses that return 202 Accepted
MUST include a Location
header pointing to a status monitor resource that represents the current state of the asynchronous processing in addition to an optional Retry-After
header indicating the time, in seconds, the client should wait before querying the service for status. Services MAY include a response body, for example, to provide additional status information.
A GET
request to the status monitor resource again returns 202 Accepted
response if the asynchronous processing has not finished. This response MUST again include a Location
header and MAY include a Retry-After
header to be used for a subsequent request. The Location
header and optional Retry-After
header may or may not contain the same values as returned by the previous request.
-A GET
request to the status monitor resource returns 200 OK
once the asynchronous processing has completed. For OData 4.01 and greater responses, or OData 4.0 requests that include an Accept
header that does not specify application/http
, the response MUST include the AsyncResult
response header. Any other headers, along with the response body, represent the result of the completed asynchronous operation. If the GET
request to the status monitor includes an OData-MaxVersion
header with a value of 4.0
and no Accept
header, or an Accept
header that includes application/http
, then the body of the final 200 OK
response MUST be represented as an HTTP message, as described in RFC7230, which is the full HTTP response to the completed asynchronous operation.
+A GET
request to the status monitor resource returns 200 OK
once the asynchronous processing has completed. For OData 4.01 and greater responses, or OData 4.0 requests that include an Accept
header that does not specify application/http
, the response MUST include the AsyncResult
response header. Any other headers, along with the response body, represent the result of the completed asynchronous operation. If the GET
request to the status monitor includes an OData-MaxVersion
header with a value of 4.0
and no Accept
header, or an Accept
header that includes application/http
, then the body of the final 200 OK
response MUST be represented as an HTTP message, as described in RFC9110, which is the full HTTP response to the completed asynchronous operation.
A DELETE
request sent to the status monitor resource requests that the asynchronous processing be canceled. A 200 OK
or a 204 No Content
response indicates that the asynchronous processing has been successfully canceled. A client can request that the DELETE
should be executed asynchronously. A 202 Accepted
response indicates that the cancellation is being processed asynchronously; the client can use the returned Location
header (which MUST be different from the status monitor resource of the initial request) to query for the status of the cancellation. If a delete request is not supported by the service, the service returns 405 Method Not Allowed
.
After a successful DELETE
request against the status monitor resource, any subsequent GET
requests for the same status monitor resource returns 404 Not Found
.
If an asynchronous request is cancelled for reasons other than the consumers issuing a DELETE
request against the status monitor resource, a GET
request to the status monitor resource returns 200 OK
with a response body containing a single HTTP response with a status code in the 5xx Server Error
range indicating that the operation was cancelled.
@@ -2864,27 +2864,22 @@ [RFC5646]
Phillips, A., Ed., and M. Davis, Ed., “Tags for Identifying Languages”, BCP 47, RFC 5646, DOI 10.17487/RFC5646, September 2009. https://www.rfc-editor.org/info/rfc5646.
[RFC5789]
Dusseault, L. and J. Snell, “PATCH Method for HTTP”, RFC 5789, DOI 10.17487/RFC5789, March 2010. https://www.rfc-editor.org/info/rfc5789.
-[RFC7230]
-Fielding, R., Ed., and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing”, RFC 7230, DOI 10.17487/RFC7230, June 2014. https://www.rfc-editor.org/info/rfc7230.
-[RFC7231]
-Fielding, R., Ed., and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content”, RFC 7231, DOI 10.17487/RFC7231, June 2014. https://www.rfc-editor.org/info/rfc7231.
-[RFC7232]
-Fielding, R., Ed., and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests”, RFC 7232, DOI 10.17487/RFC7232, June 2014. https://www.rfc-editor.org/info/rfc7232.
[RFC7240]
Snell, J., “Prefer Header for HTTP”, RFC 7240, DOI 10.17487/RFC7240, June 2014. https://www.rfc-editor.org/info/rfc7240.
[RFC7617]
Reschke, J., “The ‘Basic’ HTTP Authentication Scheme”, RFC 7617, DOI 10.17487/RFC7617, September 2015. https://www.rfc-editor.org/info/rfc7617.
[RFC8174]
Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017. https://www.rfc-editor.org/info/rfc8174.
+[RFC9110]
+Fielding, R., Ed., M. Nottingham, Ed., and J. Reschke, Ed., “HTTP Semantics”, RFC 9110, June 2022
+https://www.rfc-editor.org/info/rfc9110.
A.2 Informative References
[ECMAScript]
ECMAScript 2023 Language Specification, 14th Edition, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
-[GeoJSON-2008]
-Butler, H., Daly, M., Doyle, A., Gillies, S., Schaub, T., and C. Schmidt, “The GeoJSON Format Specification”, June 2008 http://geojson.org/geojson-spec.html.
Appendix B. Safety, Security and Privacy Considerations
This section is provided as a service to the application developers, information providers, and users of OData version 4.0 giving some references to starting points for securing OData services as specified. OData is a REST-full multi-format service that depends on other services and thus inherits both sides of the coin, security enhancements and concerns alike from the latter.
-For HTTP relevant security implications please cf. the relevant sections of RFC7231 (9. Security Considerations) and for the HTTP PATCH
method RFC5789 (5. Security Considerations) as starting points.
+For HTTP relevant security implications please cf. the relevant sections of RFC9110 (17. Security Considerations) and for the HTTP PATCH
method RFC5789 (5. Security Considerations) as starting points.
B.1 Authentication
OData Services requiring authentication SHOULD consider supporting basic authentication as defined in RFC7617 over HTTPS for the highest level of interoperability with generic clients. They MAY support other authentication methods.
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md
index ee791abb5..11dba34ab 100644
--- a/docs/odata-protocol/odata-protocol.md
+++ b/docs/odata-protocol/odata-protocol.md
@@ -846,7 +846,7 @@ additional formats for both request and response bodies.
The client MAY request a particular response format through the
[`Accept`](#HeaderAccept) header, as defined in
-[RFC7231](#rfc7231), or through the system query option
+[RFC9110](#rfc9110), or through the system query option
[`$format`](#SystemQueryOptionformat).
In the case that both the `Accept` header and the `$format` system query
@@ -911,7 +911,7 @@ parameters within the `Content-Type` header.
### 8.1.2 Header `Content-Encoding`
-As defined in [RFC7231](#rfc7231), the `Content-Encoding` header
+As defined in [RFC9110](#rfc9110), the `Content-Encoding` header
field is used as a modifier to the media-type (as indicated in the
`Content-Type` header). When present, its value indicates what additional
content codings have been applied to the entity-body.
@@ -928,7 +928,7 @@ overall batch request or response.
### 8.1.3 Header `Content-Language`
-As defined in [RFC7231](#rfc7231), a request or response can
+As defined in [RFC9110](#rfc9110), a request or response can
include a `Content-Language` header to indicate the natural language of
the intended audience for the enclosed message body. OData does not add
any additional requirements over HTTP for including `Content-Language`.
@@ -945,7 +945,7 @@ overall batch request or response.
### 8.1.4 Header `Content-Length`
-As defined in [RFC7230](#rfc7230), a request or response SHOULD
+As defined in [RFC9110](#rfc9110), a request or response SHOULD
include a `Content-Length` header when the message's length can be
determined prior to being transferred. OData does not add any additional
requirements over HTTP for writing `Content-Length`.
@@ -992,7 +992,7 @@ specify any combination of the following request headers.
### 8.2.1 Header `Accept`
-As defined in [RFC7231](#rfc7231), the client MAY specify the set
+As defined in [RFC9110](#rfc9110), the client MAY specify the set
of accepted [formats](#Formats) with the `Accept` Header.
Services MUST reject formats that specify unknown or unsupported format
@@ -1018,7 +1018,7 @@ inherit the acceptable formats of the overall batch request.
### 8.2.2 Header `Accept-Charset`
-As defined in [RFC7231](#rfc7231), the client MAY specify the set
+As defined in [RFC9110](#rfc9110), the client MAY specify the set
of accepted character sets with the `Accept-Charset` header.
If the `Accept-Charset` header is specified on an individual request
@@ -1029,7 +1029,7 @@ overall batch request.
### 8.2.3 Header `Accept-Language`
-As defined in [RFC7231](#rfc7231), the client MAY specify the set
+As defined in [RFC9110](#rfc9110), the client MAY specify the set
of accepted natural languages with the `Accept-Language` header.
If the `Accept-Language` header is specified on an individual request
@@ -1040,7 +1040,7 @@ batch request.
### 8.2.4 Header `If-Match`
-As defined in [RFC7232](#rfc7232), a client MAY include an
+As defined in [RFC9110](#rfc9110), a client MAY include an
`If-Match` header in a request to `GET`, `POST`, `PUT`, `PATCH` or
`DELETE`. The value of the `If-Match` request header MUST be an ETag
value previously retrieved for the resource, or `*` to match any value.
@@ -1062,7 +1062,7 @@ value matches the current ETag value of the target resource. Services
sending [`ETag`](#HeaderETag) headers with weak ETags that only depend
on the representation-independent entity state MUST use the weak
comparison function because it is sufficient to prevent accidental
-overwrites. This is a deviation from [RFC7232](#rfc7232).
+overwrites. This is a deviation from [RFC9110](#rfc9110).
If the value does not match the current ETag value of the resource for a
[Data Modification Request](#DataModification) or [Action
@@ -1081,14 +1081,14 @@ be specified on individual requests within the batch.
### 8.2.5 Header `If-None-Match`
-As defined in [RFC7232](#rfc7232), a client MAY include an
+As defined in [RFC9110](#rfc9110), a client MAY include an
`If-None-Match` header in a request to `GET`, `POST`, `PUT`, `PATCH` or
`DELETE`. The value of the `If-None-Match` request header MUST be an
ETag value previously retrieved for the resource, or `*`.
If present, the request MUST only be processed if the specified ETag
value does not match the current ETag value of the resource, using the
-weak comparison function (see [RFC7232](#rfc7232)). If the value
+weak comparison function (see [RFC9110](#rfc9110)). If the value
matches the current ETag value of the resource, then for a `GET`
request, the service SHOULD respond with
[`304 Not Modified`](#ResponseCode304NotModified), and for a [Data
@@ -1645,7 +1645,7 @@ within a batch.
### 8.3.2 Header `ETag`
A response MAY include an `ETag` header, see
-[RFC7232](#rfc7232). Services MUST include this header if they
+[RFC9110](#rfc9110). Services MUST include this header if they
require an ETag to be specified when modifying the resource.
Services MUST support specifying the value returned in the `ETag` header
@@ -1732,7 +1732,7 @@ to the overall batch.
### 8.3.7 Header `Retry-After`
A service MAY include a `Retry-After` header, as defined in
-[RFC7231](#rfc7231), in [`202 Accepted`](#ResponseCode202Accepted)
+[RFC9110](#rfc9110)), in [`202 Accepted`](#ResponseCode202Accepted)
and in [`3xx Redirect`](#ResponseCode3xxRedirection) responses
The `Retry-After` header specifies the duration of time, in seconds,
@@ -1757,7 +1757,7 @@ the service MUST include a `Vary` header listing the
of the response.
Alternatively, the server MAY include a `Vary` header with the special
-value `*` as defined by [RFC7231](#rfc7231), Section 8.2.1. Note
+value `*` as defined by [RFC9110](#rfc9110), Section 8.2.1. Note
that this will make it impossible for a proxy to cache the response, see
[RFC7240](#rfc7240).
@@ -1806,7 +1806,7 @@ A request returns `204 No Content` if the requested resource has the
[`return=minimal`](#Preferencereturnrepresentationandreturnminimal) preference.
In this case, the response body MUST be empty.
-As defined in [RFC7231](#rfc7231), a [Data Modification
+As defined in [RFC9110](#rfc9110), a [Data Modification
Request](#DataModification) that responds with
`204 No Content` MAY include an [`ETag`](#HeaderETag) header with a value reflecting
the result of the data modification if and only if the client can
@@ -1824,7 +1824,7 @@ server-side values corresponding to the `ETag` value sent in the
### 9.1.5 Response Code `3xx Redirection`
-As per [RFC7231](#rfc7231), a `3xx Redirection` indicates that
+As per [RFC9110](#rfc9110), a `3xx Redirection` indicates that
further action needs to be taken by the client in order to fulfill the
request. In this case, the response SHOULD include a
[`Location`](#HeaderLocation) header, as appropriate, with the URL from which the
@@ -1833,7 +1833,7 @@ result can be obtained; it MAY include a
### 9.1.6 Response Code `304 Not Modified`
-As per [RFC7232](#rfc7232), a `304 Not Modified` is returned
+As per [RFC9110](#rfc9110), a `304 Not Modified` is returned
when the client performs a `GET` request containing an
[`If-None-Match`](#HeaderIfNoneMatch) header and the content has not
changed. In this case the response SHOULD NOT include other headers in
@@ -1867,7 +1867,7 @@ does not exist. The response body MAY provide additional information.
request URL does not support the request method. In this case the
response MUST include an `Allow` header containing a list of valid
request methods for the requested resource as defined in
-[RFC7231](#rfc7231).
+[RFC9110](#rfc9110).
### 9.2.3 Response Code `406 Not Acceptable`
@@ -1889,7 +1889,7 @@ isolation](#HeaderIsolationODataIsolation).
### 9.2.5 Response Code `412 Precondition Failed`
-As defined in [RFC7232](#rfc7232), `412 Precondition Failed`
+As defined in [RFC9110](#rfc9110), `412 Precondition Failed`
indicates that the client has performed a conditional request and the
resource fails the condition. The service MUST ensure that no observable
change occurs as a result of the request.
@@ -1902,7 +1902,7 @@ depended upon a request that failed.
## 9.3 Server Error Responses
-As defined in [RFC7231](#rfc7231), error codes in the `5xx` range
+As defined in [RFC9110](#rfc9110), error codes in the `5xx` range
indicate service errors.
### 9.3.1 Response Code `501 Not Implemented`
@@ -5628,7 +5628,7 @@ asynchronous operation. If the `GET` request to the status monitor
includes an `OData-MaxVersion` header with a value of `4.0` and no
`Accept` header, or an `Accept` header that includes `application/http`,
then the body of the final `200 OK` response MUST be represented as an
-HTTP message, as described in [RFC7230](#rfc7230), which is the full
+HTTP message, as described in [RFC9110](#rfc9110), which is the full
HTTP response to the completed asynchronous operation.
A `DELETE` request sent to the status monitor resource requests that the
@@ -6768,18 +6768,6 @@ https://www.rfc-editor.org/info/rfc5646.
_Dusseault, L. and J. Snell, "PATCH Method for HTTP", RFC 5789, DOI 10.17487/RFC5789, March 2010_.
https://www.rfc-editor.org/info/rfc5789.
-###### [RFC7230]
-_Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing", RFC 7230, DOI 10.17487/RFC7230, June 2014_.
-https://www.rfc-editor.org/info/rfc7230.
-
-###### [RFC7231]
-_Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231, DOI 10.17487/RFC7231, June 2014_.
-https://www.rfc-editor.org/info/rfc7231.
-
-###### [RFC7232]
-_Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests", RFC 7232, DOI 10.17487/RFC7232, June 2014_.
-https://www.rfc-editor.org/info/rfc7232.
-
###### [RFC7240]
_Snell, J., "Prefer Header for HTTP", RFC 7240, DOI 10.17487/RFC7240, June 2014_.
https://www.rfc-editor.org/info/rfc7240.
@@ -6792,15 +6780,15 @@ https://www.rfc-editor.org/info/rfc7617.
_Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017_.
https://www.rfc-editor.org/info/rfc8174.
+###### [RFC9110]
+_Fielding, R., Ed., M. Nottingham, Ed., and J. Reschke, Ed., "HTTP Semantics", RFC 9110, June 2022_
+https://www.rfc-editor.org/info/rfc9110.
+
## A.2 Informative References
###### [ECMAScript]
_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
-###### [GeoJSON-2008]
-_Butler, H., Daly, M., Doyle, A., Gillies, S., Schaub, T., and C. Schmidt, "The GeoJSON Format Specification", June 2008_
-http://geojson.org/geojson-spec.html.
-
-------
# Appendix B. Safety, Security and Privacy Considerations
@@ -6813,7 +6801,7 @@ and thus inherits both sides of the coin, security enhancements and
concerns alike from the latter.
For HTTP relevant security implications please cf. the relevant sections
-of [RFC7231](#rfc7231) (9. Security Considerations) and for the
+of [RFC9110](#rfc9110) (17. Security Considerations) and for the
HTTP `PATCH` method [RFC5789](#rfc5789) (5. Security Considerations) as
starting points.
diff --git a/odata-protocol/1 Introduction.md b/odata-protocol/1 Introduction.md
index 68257c862..89fae2bc8 100644
--- a/odata-protocol/1 Introduction.md
+++ b/odata-protocol/1 Introduction.md
@@ -528,7 +528,7 @@ additional formats for both request and response bodies.
The client MAY request a particular response format through the
[`Accept`](#HeaderAccept) header, as defined in
-[RFC7231](#rfc7231), or through the system query option
+[RFC9110](#rfc9110), or through the system query option
[`$format`](#SystemQueryOptionformat).
In the case that both the `Accept` header and the `$format` system query
diff --git a/odata-protocol/11.5 Operations.md b/odata-protocol/11.5 Operations.md
index 1581deb2e..776ee46d4 100644
--- a/odata-protocol/11.5 Operations.md
+++ b/odata-protocol/11.5 Operations.md
@@ -501,7 +501,7 @@ asynchronous operation. If the `GET` request to the status monitor
includes an `OData-MaxVersion` header with a value of `4.0` and no
`Accept` header, or an `Accept` header that includes `application/http`,
then the body of the final `200 OK` response MUST be represented as an
-HTTP message, as described in [RFC7230](#rfc7230), which is the full
+HTTP message, as described in [RFC9110](#rfc9110), which is the full
HTTP response to the completed asynchronous operation.
A `DELETE` request sent to the status monitor resource requests that the
diff --git a/odata-protocol/8 Header Fields.md b/odata-protocol/8 Header Fields.md
index 12f946af8..90ab47503 100644
--- a/odata-protocol/8 Header Fields.md
+++ b/odata-protocol/8 Header Fields.md
@@ -32,7 +32,7 @@ parameters within the `Content-Type` header.
### ##subsubsec Header `Content-Encoding`
-As defined in [RFC7231](#rfc7231), the `Content-Encoding` header
+As defined in [RFC9110](#rfc9110), the `Content-Encoding` header
field is used as a modifier to the media-type (as indicated in the
`Content-Type` header). When present, its value indicates what additional
content codings have been applied to the entity-body.
@@ -49,7 +49,7 @@ overall batch request or response.
### ##subsubsec Header `Content-Language`
-As defined in [RFC7231](#rfc7231), a request or response can
+As defined in [RFC9110](#rfc9110), a request or response can
include a `Content-Language` header to indicate the natural language of
the intended audience for the enclosed message body. OData does not add
any additional requirements over HTTP for including `Content-Language`.
@@ -66,7 +66,7 @@ overall batch request or response.
### ##subsubsec Header `Content-Length`
-As defined in [RFC7230](#rfc7230), a request or response SHOULD
+As defined in [RFC9110](#rfc9110), a request or response SHOULD
include a `Content-Length` header when the message's length can be
determined prior to being transferred. OData does not add any additional
requirements over HTTP for writing `Content-Length`.
@@ -113,7 +113,7 @@ specify any combination of the following request headers.
### ##subsubsec Header `Accept`
-As defined in [RFC7231](#rfc7231), the client MAY specify the set
+As defined in [RFC9110](#rfc9110), the client MAY specify the set
of accepted [formats](#Formats) with the `Accept` Header.
Services MUST reject formats that specify unknown or unsupported format
@@ -139,7 +139,7 @@ inherit the acceptable formats of the overall batch request.
### ##subsubsec Header `Accept-Charset`
-As defined in [RFC7231](#rfc7231), the client MAY specify the set
+As defined in [RFC9110](#rfc9110), the client MAY specify the set
of accepted character sets with the `Accept-Charset` header.
If the `Accept-Charset` header is specified on an individual request
@@ -150,7 +150,7 @@ overall batch request.
### ##subsubsec Header `Accept-Language`
-As defined in [RFC7231](#rfc7231), the client MAY specify the set
+As defined in [RFC9110](#rfc9110), the client MAY specify the set
of accepted natural languages with the `Accept-Language` header.
If the `Accept-Language` header is specified on an individual request
@@ -161,7 +161,7 @@ batch request.
### ##subsubsec Header `If-Match`
-As defined in [RFC7232](#rfc7232), a client MAY include an
+As defined in [RFC9110](#rfc9110), a client MAY include an
`If-Match` header in a request to `GET`, `POST`, `PUT`, `PATCH` or
`DELETE`. The value of the `If-Match` request header MUST be an ETag
value previously retrieved for the resource, or `*` to match any value.
@@ -183,7 +183,7 @@ value matches the current ETag value of the target resource. Services
sending [`ETag`](#HeaderETag) headers with weak ETags that only depend
on the representation-independent entity state MUST use the weak
comparison function because it is sufficient to prevent accidental
-overwrites. This is a deviation from [RFC7232](#rfc7232).
+overwrites. This is a deviation from [RFC9110](#rfc9110).
If the value does not match the current ETag value of the resource for a
[Data Modification Request](#DataModification) or [Action
@@ -202,14 +202,14 @@ be specified on individual requests within the batch.
### ##subsubsec Header `If-None-Match`
-As defined in [RFC7232](#rfc7232), a client MAY include an
+As defined in [RFC9110](#rfc9110), a client MAY include an
`If-None-Match` header in a request to `GET`, `POST`, `PUT`, `PATCH` or
`DELETE`. The value of the `If-None-Match` request header MUST be an
ETag value previously retrieved for the resource, or `*`.
If present, the request MUST only be processed if the specified ETag
value does not match the current ETag value of the resource, using the
-weak comparison function (see [RFC7232](#rfc7232)). If the value
+weak comparison function (see [RFC9110](#rfc9110)). If the value
matches the current ETag value of the resource, then for a `GET`
request, the service SHOULD respond with
[`304 Not Modified`](#ResponseCode304NotModified), and for a [Data
@@ -769,7 +769,7 @@ within a batch.
### ##subsubsec Header `ETag`
A response MAY include an `ETag` header, see
-[RFC7232](#rfc7232). Services MUST include this header if they
+[RFC9110](#rfc9110). Services MUST include this header if they
require an ETag to be specified when modifying the resource.
Services MUST support specifying the value returned in the `ETag` header
@@ -856,7 +856,7 @@ to the overall batch.
### ##subsubsec Header `Retry-After`
A service MAY include a `Retry-After` header, as defined in
-[RFC7231](#rfc7231), in [`202 Accepted`](#ResponseCode202Accepted)
+[RFC9110](#rfc9110)), in [`202 Accepted`](#ResponseCode202Accepted)
and in [`3xx Redirect`](#ResponseCode3xxRedirection) responses
The `Retry-After` header specifies the duration of time, in seconds,
@@ -881,7 +881,7 @@ the service MUST include a `Vary` header listing the
of the response.
Alternatively, the server MAY include a `Vary` header with the special
-value `*` as defined by [RFC7231](#rfc7231), Section 8.2.1. Note
+value `*` as defined by [RFC9110](#rfc9110), Section 8.2.1. Note
that this will make it impossible for a proxy to cache the response, see
[RFC7240](#rfc7240).
@@ -930,7 +930,7 @@ A request returns `204 No Content` if the requested resource has the
[`return=minimal`](#Preferencereturnrepresentationandreturnminimal) preference.
In this case, the response body MUST be empty.
-As defined in [RFC7231](#rfc7231), a [Data Modification
+As defined in [RFC9110](#rfc9110), a [Data Modification
Request](#DataModification) that responds with
`204 No Content` MAY include an [`ETag`](#HeaderETag) header with a value reflecting
the result of the data modification if and only if the client can
@@ -948,7 +948,7 @@ server-side values corresponding to the `ETag` value sent in the
### ##subsubsec Response Code `3xx Redirection`
-As per [RFC7231](#rfc7231), a `3xx Redirection` indicates that
+As per [RFC9110](#rfc9110), a `3xx Redirection` indicates that
further action needs to be taken by the client in order to fulfill the
request. In this case, the response SHOULD include a
[`Location`](#HeaderLocation) header, as appropriate, with the URL from which the
@@ -957,7 +957,7 @@ result can be obtained; it MAY include a
### ##subsubsec Response Code `304 Not Modified`
-As per [RFC7232](#rfc7232), a `304 Not Modified` is returned
+As per [RFC9110](#rfc9110), a `304 Not Modified` is returned
when the client performs a `GET` request containing an
[`If-None-Match`](#HeaderIfNoneMatch) header and the content has not
changed. In this case the response SHOULD NOT include other headers in
@@ -991,7 +991,7 @@ does not exist. The response body MAY provide additional information.
request URL does not support the request method. In this case the
response MUST include an `Allow` header containing a list of valid
request methods for the requested resource as defined in
-[RFC7231](#rfc7231).
+[RFC9110](#rfc9110).
### ##subsubsec Response Code `406 Not Acceptable`
@@ -1013,7 +1013,7 @@ isolation](#HeaderIsolationODataIsolation).
### ##subsubsec Response Code `412 Precondition Failed`
-As defined in [RFC7232](#rfc7232), `412 Precondition Failed`
+As defined in [RFC9110](#rfc9110), `412 Precondition Failed`
indicates that the client has performed a conditional request and the
resource fails the condition. The service MUST ensure that no observable
change occurs as a result of the request.
@@ -1026,7 +1026,7 @@ depended upon a request that failed.
## ##subsec Server Error Responses
-As defined in [RFC7231](#rfc7231), error codes in the `5xx` range
+As defined in [RFC9110](#rfc9110), error codes in the `5xx` range
indicate service errors.
### ##subsubsec Response Code `501 Not Implemented`
diff --git a/odata-protocol/Appendix.md b/odata-protocol/Appendix.md
index caa5ac333..98c05d4e4 100644
--- a/odata-protocol/Appendix.md
+++ b/odata-protocol/Appendix.md
@@ -62,18 +62,6 @@ https://www.rfc-editor.org/info/rfc5646.
_Dusseault, L. and J. Snell, "PATCH Method for HTTP", RFC 5789, DOI 10.17487/RFC5789, March 2010_.
https://www.rfc-editor.org/info/rfc5789.
-###### [RFC7230]
-_Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing", RFC 7230, DOI 10.17487/RFC7230, June 2014_.
-https://www.rfc-editor.org/info/rfc7230.
-
-###### [RFC7231]
-_Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231, DOI 10.17487/RFC7231, June 2014_.
-https://www.rfc-editor.org/info/rfc7231.
-
-###### [RFC7232]
-_Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests", RFC 7232, DOI 10.17487/RFC7232, June 2014_.
-https://www.rfc-editor.org/info/rfc7232.
-
###### [RFC7240]
_Snell, J., "Prefer Header for HTTP", RFC 7240, DOI 10.17487/RFC7240, June 2014_.
https://www.rfc-editor.org/info/rfc7240.
@@ -86,16 +74,16 @@ https://www.rfc-editor.org/info/rfc7617.
_Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017_.
https://www.rfc-editor.org/info/rfc8174.
+###### [RFC9110]
+_Fielding, R., Ed., M. Nottingham, Ed., and J. Reschke, Ed., "HTTP Semantics", RFC 9110, June 2022_
+https://www.rfc-editor.org/info/rfc9110.
+
## ##subasec Informative References
###### [ECMAScript]
_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262.
https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
-###### [GeoJSON-2008]
-_Butler, H., Daly, M., Doyle, A., Gillies, S., Schaub, T., and C. Schmidt, "The GeoJSON Format Specification", June 2008_
-http://geojson.org/geojson-spec.html.
-
-------
# Appendix ##asec Safety, Security and Privacy Considerations
@@ -108,7 +96,7 @@ and thus inherits both sides of the coin, security enhancements and
concerns alike from the latter.
For HTTP relevant security implications please cf. the relevant sections
-of [RFC7231](#rfc7231) (9. Security Considerations) and for the
+of [RFC9110](#rfc9110) (17. Security Considerations) and for the
HTTP `PATCH` method [RFC5789](#rfc5789) (5. Security Considerations) as
starting points.
From f534bf12d9e1384d7a2123099d572fa3b181edcd Mon Sep 17 00:00:00 2001
From: Ralf Handl
Date: Wed, 29 Nov 2023 18:45:00 +0100
Subject: [PATCH 17/22] ODATA-1604 (#201)
---
docs/odata-url-conventions/odata-url-conventions.html | 2 +-
docs/odata-url-conventions/odata-url-conventions.md | 1 +
odata-url-conventions/5 Query Options.md | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html
index c46720cab..b197af820 100644
--- a/docs/odata-url-conventions/odata-url-conventions.html
+++ b/docs/odata-url-conventions/odata-url-conventions.html
@@ -1892,7 +1892,7 @@ 5.1.8.1 Search Expressions
-
Search expressions are used within the $search
system query option to request entities matching the specified expression.
+Search expressions are used within the $search
system query option to request entities matching the specified expression. Leading and trailing spaces are not considered part of the search expression.
Terms can be any single word to be matched within the expression.
Terms enclosed in double-quotes comprise a phrase.
Each individual term or phrase comprises a Boolean expression that returns true if the term or phrase is matched, otherwise false. The semantics of what is considered a match is dependent upon the service.
diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md
index df2a97f34..0fcacf618 100644
--- a/docs/odata-url-conventions/odata-url-conventions.md
+++ b/docs/odata-url-conventions/odata-url-conventions.md
@@ -3716,6 +3716,7 @@ http://host/service/Products?$search=blue OR green
Search expressions are used within the
[`$search`](#SystemQueryOptionsearch) system query option to request
entities matching the specified expression.
+Leading and trailing spaces are not considered part of the search expression.
*Terms* can be any single word to be matched within the expression.
diff --git a/odata-url-conventions/5 Query Options.md b/odata-url-conventions/5 Query Options.md
index 6bb1854a0..8ee9653e0 100644
--- a/odata-url-conventions/5 Query Options.md
+++ b/odata-url-conventions/5 Query Options.md
@@ -2317,6 +2317,7 @@ http://host/service/Products?$search=blue OR green
Search expressions are used within the
[`$search`](#SystemQueryOptionsearch) system query option to request
entities matching the specified expression.
+Leading and trailing spaces are not considered part of the search expression.
*Terms* can be any single word to be matched within the expression.
From 36e0daa7c0d4115865337f8fcf2d2824f60c8666 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Thu, 30 Nov 2023 17:07:09 +0100
Subject: [PATCH 18/22] Code block cosmetics (#220)
---
docs/odata-csdl-json/odata-csdl-json.html | 634 +++++++++---------
docs/odata-csdl-json/odata-csdl-json.md | 82 ++-
docs/odata-csdl-xml/odata-csdl-xml.html | 352 +++++-----
docs/odata-csdl-xml/odata-csdl-xml.md | 68 +-
.../odata-data-aggregation-ext.html | 58 +-
.../odata-data-aggregation-ext.md | 60 +-
docs/odata-json-format/odata-json-format.html | 124 ++--
docs/odata-json-format/odata-json-format.md | 122 ++--
docs/odata-protocol/odata-protocol.html | 45 +-
docs/odata-protocol/odata-protocol.md | 27 +-
.../odata-url-conventions.html | 195 +++---
.../odata-url-conventions.md | 111 ++-
odata-csdl/13 Entity Container.md | 4 +-
odata-csdl/14 Vocabulary and Annotation.md | 34 +-
odata-csdl/15 Identifier and Path Values.md | 12 +
odata-csdl/4 CSDL Document.md | 34 +-
odata-csdl/5 Schema.md | 12 +-
odata-csdl/7 Structural Property.md | 20 +-
odata-csdl/9 Complex Type.md | 8 +-
odata-data-aggregation-ext/1 Introduction.md | 2 +-
.../3.2 Basic Aggregation.md | 8 +-
.../4 Cross-Joins and Aggregation.md | 2 +-
.../5 Vocabulary for Data Aggregation.md | 14 +-
.../6 Hierarchical Transformations.md | 8 +-
odata-data-aggregation-ext/7 Examples.md | 26 +-
odata-json-format/10 Media Entity.md | 16 +-
odata-json-format/15 Delta Payload.md | 30 +-
odata-json-format/16 Bound Function.md | 16 +-
.../19 Batch Requests and Responses.md | 2 +-
odata-json-format/20 Instance Annotations.md | 4 +-
odata-json-format/4 Common Characteristics.md | 16 +-
odata-json-format/7 Structural Property.md | 38 +-
odata-protocol/10 Context URL.md | 2 +-
odata-protocol/11.4 Data Modification.md | 13 +-
odata-protocol/11.5 Operations.md | 10 +-
odata-protocol/11.7 Batch Requests.md | 2 +-
odata-url-conventions/1 Introduction.md | 10 +
odata-url-conventions/4 Resource Path.md | 42 +-
odata-url-conventions/5 Query Options.md | 59 +-
39 files changed, 1239 insertions(+), 1083 deletions(-)
diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html
index 410f6e9cd..a8fcf83d1 100644
--- a/docs/odata-csdl-json/odata-csdl-json.html
+++ b/docs/odata-csdl-json/odata-csdl-json.html
@@ -805,7 +805,7 @@ {
"$Version": "4.01",
"$EntityContainer": "org.example.DemoService",
- ...
+ …
}
@@ -824,19 +824,19 @@
Example 8: references to other CSDL documents
{
-...
+ …
"$Reference": {
"https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
- ...
+ …
},
"https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
- ...
+ …
},
"http://example.org/display/v1": {
- ...
+ …
}
},
- ...
+ …
}
4.2 Included Schema
@@ -861,7 +861,7 @@ $Alias
Example 9: references to entity models containing definitions of vocabulary terms
{
-...
+ …
"$Reference": {
"https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
"$Include": [
@@ -889,7 +889,7 @@ $Alias
]
}
},
- ...
+ …
}
4.3 Included Annotations
@@ -912,7 +912,7 @@
Example 10: reference documents that contain annotations
{
-...
+ …
"$Reference": {
"http://odata.org/ann/b": {
"$IncludeAnnotations": [
@@ -935,7 +935,7 @@ ]
}
},
- ...
+ …
}
@@ -973,13 +973,13 @@ $Alias
Example 11: document defining a schema org.example
with an alias and a description for the schema
{
-...
+ …
"org.example": {
"$Alias": "self",
"@Core.Description": "Example schema",
- ...
+ …
},
- ...
+ …
}
5.2 Annotations with External Targeting
@@ -994,7 +994,7 @@ $Annotations
"$Annotations": {
"self.Person": {
"@Core.Description#Tablet": "Dummy",
- ...
+ …
}
}
}
@@ -1263,7 +1263,7 @@ Navig
Example 22: the Product
entity type has a navigation property to a Category
, which has a navigation link back to one or more products
"Product": {
"$Kind": "EntityType",
- ...
+ …
"Category": {
"$Kind": "NavigationProperty",
"$Type": "self.Category",
@@ -1279,7 +1279,7 @@ Navig
},
"Category": {
"$Kind": "EntityType",
- ...
+ …
"Products": {
"$Kind": "NavigationProperty",
"$Collection": true,
@@ -1351,7 +1351,7 @@ $
Example 23: the category must exist for a product in that category to exist. The CategoryID
of the product is identical to the ID
of the category, and the CategoryKind
property of the product is identical to the Kind
property of the category.
"Product": {
"$Kind": "EntityType",
- ...
+ …
"CategoryID": {},
"CategoryKind": {},
"Category": {
@@ -1374,7 +1374,7 @@ $
"Kind": {
"$Nullable": true
},
- ...
+ …
}
8.6 On-Delete Action
@@ -1396,7 +1396,7 @@ $OnDelete
Example 24: deletion of a category implies deletion of the related products in that category
"Category": {
"$Kind": "EntityType",
- ...
+ …
"Products": {
"$Kind": "NavigationProperty",
"$Collection": true,
@@ -1436,7 +1436,7 @@ Complex Type Object
}
},
"Product": {
-...
+ …
"ProductDimensions": {
"$Nullable": true,
"$Type": "self.Dimensions"
@@ -1447,7 +1447,7 @@ Complex Type Object
}
},
"ShipmentBox": {
-...
+ …
"Dimensions": {
"$Nullable": true,
"$Type": "self.Dimensions"
@@ -1844,7 +1844,7 @@ $Extends
"Extending": {
"$Kind": "EntityContainer",
"$Extends": "Some.Other.Schema.Base",
- ...
+ …
}
13.2 Entity Set
@@ -2203,10 +2203,9 @@ $AppliesTo
"Property",
"Term"
],
- "@Core.Description": "Properties and terms annotated with this term
-MUST contain a valid URL",
- "@Core.RequiresType": "Edm.String"
-}
+ "@Core.Description": "Properties and terms annotated with this term MUST contain a valid URL",
+ "@Core.RequiresType": "Edm.String"
+}
An annotation applies a term to a model element and defines how to calculate a value for the term application. Both term and model element MUST be in scope. Section 14.1.2 specifies which model elements MAY be annotated with a term.
@@ -2528,7 +2527,7 @@If a path segment is a qualified name, it represents a type cast, and the segment MUST be the name of a type in scope. If the type or instance identified by the preceding path part cannot be cast to the specified type, the path expression evaluates to the null value.
Example 60: type-cast segment
-.../self.Manager/...
+…/self.Manager/…
If a path segment starts with an at (@
) character, it represents a term cast. The at (@
) character MUST be followed by a qualified name that MAY be followed by a hash (#
) character and a simple identifier. The qualified name preceding the hash character MUST resolve to a term that is in scope, the simple identifier following the hash sign is interpreted as a qualifier for the term. If the model element or instance identified by the preceding path part has not been annotated with that term (and if present, with that qualifier), the term cast evaluates to the null value. Four special terms are implicitly “annotated” for media entities and stream properties:
Example 61: term-cast segments
-.../@Capabilities.SortRestrictions/...
+…/@Capabilities.SortRestrictions/…
If a path segment is a simple identifier, it MUST be the name of a child model element of the model element identified by the preceding path part, or a structural or navigation property of the instance identified by the preceding path part. A sequence of navigation segments can traverse multiple CSDL documents. The document containing the path expression only needs to reference the next traversed document to bring the navigation target type into scope, and each traversed document in turn needs to reference only its next document.
A model path MAY contain any number of segments representing collection-valued structural or navigation properties. The result of the expression is the model element reached via this path.
Example 62: property segments in model path
-.../Orders/Items/Product/...
+…/Orders/Items/Product/…
An instance path MUST NOT contain more than one segment representing a collection-valued construct, e.g. an entity set or a collection-valued navigation property that is not followed by a key predicate, or a collection-valued structural property that is not followed by an index segment. The result of the expression is the collection of instances resulting from applying any remaining path segments that operate on a single-valued expression to each instance in the collection-valued segment.
An instance path MAY terminate in a $count
segment if the previous segment is collection-valued, in which case the path evaluates to the number of items in the collection identified by the preceding segment.
Example 63: property segments in instance path
-.../Addresses/Street
-.../Addresses/$count
+…/Addresses/Street
+…/Addresses/$count
A model path MAY contain path segments starting with a navigation property, then followed by an at (@
) character, then followed by the qualified name of a term in scope, and optionally followed by a hash (#
) character and a simple identifier which is interpreted as a qualifier for the term. If the navigation property has not been annotated with that term (and if present, with that qualifier), the path segment evaluates to the null value. This allows addressing annotations on the navigation property itself; annotations on the entity type specified by the navigation property are addressed via a term-cast segment.
Example 64: model path segment addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property
-.../Items@Core.Description
-.../Items/@Core.Description
+…/Items@Core.Description
+…/Items/@Core.Description
An instance path MAY contain path segments starting with an entity set or a collection-valued navigation property, then followed by a key predicate using parentheses-style convention, see OData-URL. The key values are either primitive literals or instance paths. If the key value is a relative instance path, it is interpreted according to the same rule below as the instance path it is part of, not relative to the instance identified by the preceding path part.
Example 70:
"@UI.HyperLink": "Supplier",
-
-"@Capabilities.UpdateRestrictions": {
-"NonUpdatableNavigationProperties": [
- "Supplier",
- "Category"
- ]
- }
The property path expression provides a value for terms or term properties that specify one of the built-in types Edm.PropertyPath
, Edm.AnyPropertyPath
, or Edm.ModelElementPath
. Its argument is a model path with the following restriction:
Example 71:
"@UI.RefreshOnChangeOf": "ChangedAt",
-
-"@Capabilities.UpdateRestrictions": {
-"NonUpdatableProperties": [
- "CreatedAt",
- "ChangedAt"
- ]
- }
The value path expression allows assigning a value by traversing an object graph. It can be used in annotations that target entity containers, entity sets, entity types, complex types, navigation properties of structured types, and structural properties of structured types. Its argument is an instance path.
@@ -2730,10 +2727,9 @@$Path
"@UI.DisplayName": {
"$Path": "FirstName"
},
-
-"@UI.DisplayName#second": {
-"$Path": "@vCard.Address#work/FullName"
- }
Annotations MAY use the following logical and comparison expressions which evaluate to a Boolean value. These expressions MAY be combined and they MAY be used anywhere instead of a Boolean expression.
@@ -3295,11 +3291,11 @@Example 89: Target expressions
-MySchema.MyEntityContainer/MyEntitySet
-MySchema.MyEntityContainer/MySingleton
-MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty
-MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty
-MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp
+MySchema.MyEntityContainer/MyEntitySet
+MySchema.MyEntityContainer/MySingleton
+MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty
+MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty
+MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp
Example 90:
-{
-"$Version": "4.0",
- "$EntityContainer": "ODataDemo.DemoService",
- "$Reference": {
- "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
- "$Include": [
- {
- "$Namespace": "Org.OData.Core.V1",
- "$Alias": "Core",
- "@Core.DefaultNamespace": true
- }
- ]
- },
- "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json": {
- "$Include": [
- {
- "$Namespace": "Org.OData.Measures.V1",
- "$Alias": "Measures"
- }
- ]
- }
- },
- "ODataDemo": {
- "$Alias": "self",
- "@Core.DefaultNamespace": true,
- "Product": {
- "$Kind": "EntityType",
- "$Key": [
- "ID"
- ],
- "ID": {},
- "Description": {
- "$Nullable": true,
- "@Core.IsLanguageDependent": true
- },
- "ReleaseDate": {
- "$Nullable": true,
- "$Type": "Edm.Date"
- },
- "DiscontinuedDate": {
- "$Nullable": true,
- "$Type": "Edm.Date"
- },
- "Rating": {
- "$Nullable": true,
- "$Type": "Edm.Int32"
- },
- "Price": {
- "$Nullable": true,
- "$Type": "Edm.Decimal",
- "@Measures.ISOCurrency": {
- "$Path": "Currency"
- }
- },
- "Currency": {
- "$Nullable": true,
- "$MaxLength": 3
- },
- "Category": {
- "$Kind": "NavigationProperty",
- "$Type": "self.Category",
- "$Partner": "Products"
- },
- "Supplier": {
- "$Kind": "NavigationProperty",
- "$Nullable": true,
- "$Type": "self.Supplier",
- "$Partner": "Products"
- }
- },
- "Category": {
- "$Kind": "EntityType",
- "$Key": [
- "ID"
- ],
- "ID": {
- "$Type": "Edm.Int32"
- },
- "Name": {
- "@Core.IsLanguageDependent": true
- },
- "Products": {
- "$Kind": "NavigationProperty",
- "$Partner": "Category",
- "$Collection": true,
- "$Type": "self.Product",
- "$OnDelete": "Cascade"
- }
- },
- "Supplier": {
- "$Kind": "EntityType",
- "$Key": [
- "ID"
- ],
- "ID": {},
- "Name": {
- "$Nullable": true
- },
- "Address": {
- "$Type": "self.Address"
- },
- "Concurrency": {
- "$Type": "Edm.Int32"
- },
- "Products": {
- "$Kind": "NavigationProperty",
- "$Partner": "Supplier",
- "$Collection": true,
- "$Type": "self.Product"
- }
- },
- "Country": {
- "$Kind": "EntityType",
- "$Key": [
- "Code"
- ],
- "Code": {
- "$MaxLength": 2
- },
- "Name": {
- "$Nullable": true
- }
- },
- "Address": {
- "$Kind": "ComplexType",
- "Street": {
- "$Nullable": true
- },
- "City": {
- "$Nullable": true
- },
- "State": {
- "$Nullable": true
- },
- "ZipCode": {
- "$Nullable": true
- },
- "CountryName": {
- "$Nullable": true
- },
- "Country": {
- "$Kind": "NavigationProperty",
- "$Nullable": true,
- "$Type": "self.Country",
- "$ReferentialConstraint": {
- "CountryName": "Name"
- }
- }
- },
- "ProductsByRating": [
- {
- "$Kind": "Function",
- "$Parameter": [
- {
- "$Name": "Rating",
- "$Nullable": true,
- "$Type": "Edm.Int32"
- }
- ],
- "$ReturnType": {
- "$Collection": true,
- "$Type": "self.Product"
- }
- }
- ],
- "DemoService": {
- "$Kind": "EntityContainer",
- "Products": {
- "$Collection": true,
- "$Type": "self.Product",
- "$NavigationPropertyBinding": {
- "Category": "Categories"
- }
- },
- "Categories": {
- "$Collection": true,
- "$Type": "self.Category",
- "$NavigationPropertyBinding": {
- "Products": "Products"
- },
- "@Core.Description": "Product Categories"
- },
- "Suppliers": {
- "$Collection": true,
- "$Type": "self.Supplier",
- "$NavigationPropertyBinding": {
- "Products": "Products",
- "Address/Country": "Countries"
- },
- "@Core.OptimisticConcurrency": [
- "Concurrency"
- ]
- },
- "Countries": {
- "$Collection": true,
- "$Type": "self.Country"
- },
- "MainSupplier": {
- "$Type": "self.Supplier",
- "$NavigationPropertyBinding": {
- "Products": "Products"
- },
- "@Core.Description": "Primary Supplier"
- },
- "ProductsByRating": {
- "$EntitySet": "Products",
- "$Function": "self.ProductsByRating"
- }
- }
- }
- }
{
+"$Version": "4.0",
+ "$EntityContainer": "ODataDemo.DemoService",
+ "$Reference": {
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
+ "$Include": [
+ {
+ "$Namespace": "Org.OData.Core.V1",
+ "$Alias": "Core",
+ "@Core.DefaultNamespace": true
+ }
+ ]
+ },
+ "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.json": {
+ "$Include": [
+ {
+ "$Namespace": "Org.OData.Measures.V1",
+ "$Alias": "Measures"
+ }
+ ]
+ }
+ },
+ "ODataDemo": {
+ "$Alias": "self",
+ "@Core.DefaultNamespace": true,
+ "Product": {
+ "$Kind": "EntityType",
+ "$Key": [
+ "ID"
+ ],
+ "ID": {},
+ "Description": {
+ "$Nullable": true,
+ "@Core.IsLanguageDependent": true
+ },
+ "ReleaseDate": {
+ "$Nullable": true,
+ "$Type": "Edm.Date"
+ },
+ "DiscontinuedDate": {
+ "$Nullable": true,
+ "$Type": "Edm.Date"
+ },
+ "Rating": {
+ "$Nullable": true,
+ "$Type": "Edm.Int32"
+ },
+ "Price": {
+ "$Nullable": true,
+ "$Type": "Edm.Decimal",
+ "@Measures.ISOCurrency": {
+ "$Path": "Currency"
+ }
+ },
+ "Currency": {
+ "$Nullable": true,
+ "$MaxLength": 3
+ },
+ "Category": {
+ "$Kind": "NavigationProperty",
+ "$Type": "self.Category",
+ "$Partner": "Products"
+ },
+ "Supplier": {
+ "$Kind": "NavigationProperty",
+ "$Nullable": true,
+ "$Type": "self.Supplier",
+ "$Partner": "Products"
+ }
+ },
+ "Category": {
+ "$Kind": "EntityType",
+ "$Key": [
+ "ID"
+ ],
+ "ID": {
+ "$Type": "Edm.Int32"
+ },
+ "Name": {
+ "@Core.IsLanguageDependent": true
+ },
+ "Products": {
+ "$Kind": "NavigationProperty",
+ "$Partner": "Category",
+ "$Collection": true,
+ "$Type": "self.Product",
+ "$OnDelete": "Cascade"
+ }
+ },
+ "Supplier": {
+ "$Kind": "EntityType",
+ "$Key": [
+ "ID"
+ ],
+ "ID": {},
+ "Name": {
+ "$Nullable": true
+ },
+ "Address": {
+ "$Type": "self.Address"
+ },
+ "Concurrency": {
+ "$Type": "Edm.Int32"
+ },
+ "Products": {
+ "$Kind": "NavigationProperty",
+ "$Partner": "Supplier",
+ "$Collection": true,
+ "$Type": "self.Product"
+ }
+ },
+ "Country": {
+ "$Kind": "EntityType",
+ "$Key": [
+ "Code"
+ ],
+ "Code": {
+ "$MaxLength": 2
+ },
+ "Name": {
+ "$Nullable": true
+ }
+ },
+ "Address": {
+ "$Kind": "ComplexType",
+ "Street": {
+ "$Nullable": true
+ },
+ "City": {
+ "$Nullable": true
+ },
+ "State": {
+ "$Nullable": true
+ },
+ "ZipCode": {
+ "$Nullable": true
+ },
+ "CountryName": {
+ "$Nullable": true
+ },
+ "Country": {
+ "$Kind": "NavigationProperty",
+ "$Nullable": true,
+ "$Type": "self.Country",
+ "$ReferentialConstraint": {
+ "CountryName": "Name"
+ }
+ }
+ },
+ "ProductsByRating": [
+ {
+ "$Kind": "Function",
+ "$Parameter": [
+ {
+ "$Name": "Rating",
+ "$Nullable": true,
+ "$Type": "Edm.Int32"
+ }
+ ],
+ "$ReturnType": {
+ "$Collection": true,
+ "$Type": "self.Product"
+ }
+ }
+ ],
+ "DemoService": {
+ "$Kind": "EntityContainer",
+ "Products": {
+ "$Collection": true,
+ "$Type": "self.Product",
+ "$NavigationPropertyBinding": {
+ "Category": "Categories"
+ }
+ },
+ "Categories": {
+ "$Collection": true,
+ "$Type": "self.Category",
+ "$NavigationPropertyBinding": {
+ "Products": "Products"
+ },
+ "@Core.Description": "Product Categories"
+ },
+ "Suppliers": {
+ "$Collection": true,
+ "$Type": "self.Supplier",
+ "$NavigationPropertyBinding": {
+ "Products": "Products",
+ "Address/Country": "Countries"
+ },
+ "@Core.OptimisticConcurrency": [
+ "Concurrency"
+ ]
+ },
+ "Countries": {
+ "$Collection": true,
+ "$Type": "self.Country"
+ },
+ "MainSupplier": {
+ "$Type": "self.Supplier",
+ "$NavigationPropertyBinding": {
+ "Products": "Products"
+ },
+ "@Core.Description": "Primary Supplier"
+ },
+ "ProductsByRating": {
+ "$EntitySet": "Products",
+ "$Function": "self.ProductsByRating"
+ }
+ }
+ }
+ }
Example 91:
-{
-"$Version": "4.01",
- "$Reference": {
- "http://host/service/$metadata": {
- "$Include": [
- {
- "$Namespace": "ODataDemo",
- "$Alias": "target"
- }
- ]
- },
- "http://somewhere/Vocabulary/V1": {
- "$Include": [
- {
- "$Namespace": "Some.Vocabulary.V1",
- "$Alias": "Vocabulary1"
- }
- ]
- }
- },
- "External.Annotations": {
- "$Annotations": {
- "target.Supplier": {
- "@Vocabulary1.EMail": null,
- "@Vocabulary1.AccountID": {
- "$Path": "ID"
- },
- "@Vocabulary1.Title": "Supplier Info",
- "@Vocabulary1.DisplayName": {
- "$Apply": [
- {
- "$Path": "Name"
- },
- " in ",
- {
- "$Path": "Address/CountryName"
- }
- ],
- "$Function": "odata.concat"
- }
- },
- "target.Product": {
- "@Vocabulary1.Tags": [
- "MasterData"
- ]
- }
- }
- }
- }
{
+"$Version": "4.01",
+ "$Reference": {
+ "http://host/service/$metadata": {
+ "$Include": [
+ {
+ "$Namespace": "ODataDemo",
+ "$Alias": "target"
+ }
+ ]
+ },
+ "http://somewhere/Vocabulary/V1": {
+ "$Include": [
+ {
+ "$Namespace": "Some.Vocabulary.V1",
+ "$Alias": "Vocabulary1"
+ }
+ ]
+ }
+ },
+ "External.Annotations": {
+ "$Annotations": {
+ "target.Supplier": {
+ "@Vocabulary1.EMail": null,
+ "@Vocabulary1.AccountID": {
+ "$Path": "ID"
+ },
+ "@Vocabulary1.Title": "Supplier Info",
+ "@Vocabulary1.DisplayName": {
+ "$Apply": [
+ {
+ "$Path": "Name"
+ },
+ " in ",
+ {
+ "$Path": "Address/CountryName"
+ }
+ ],
+ "$Function": "odata.concat"
+ }
+ },
+ "target.Product": {
+ "@Vocabulary1.Tags": [
+ "MasterData"
+ ]
+ }
+ }
+ }
+ }
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
Version="4.01">
<edmx:DataServices>
- ...
+ …
</edmx:DataServices>
</edmx:Edmx>
@@ -806,16 +806,16 @@ <Annotations Target="org.example.Person" Qualifier="Tablet">
<Annotation Term="Core.Description" String="Dummy" />
- ...
+ …
</Annotations>
Example 22: the Product entity type has a navigation property to a Category, which has a navigation link back to one or more products
EntityType Name="Product">
- <
+ ...
…NavigationProperty Name="Category" Type="self.Category" Nullable="false"
< Partner="Products" />
NavigationProperty Name="Supplier" Type="self.Supplier" />
<EntityType>
</
EntityType Name="Category">
- <
+ ...
…NavigationProperty Name="Products" Type="Collection(self.Product)"
< Partner="Category" />
EntityType> </
Example 23: the category must exist for a product in that category to exist. The CategoryID
of the product is identical to the ID
of the category, and the CategoryKind
property of the product is identical to the Kind
property of the category.
EntityType Name="Product">
- <
+ ...
…Property Name="CategoryID" Type="Edm.String" Nullable="false"/>
<Property Name="CategoryKind" Type="Edm.String" Nullable="true" />
<NavigationProperty Name="Category" Type="self.Category" Nullable="false">
@@ -1271,7 +1271,7 @@ < </Key>
Property Name="ID" Type="Edm.String" Nullable="false" />
<Property Name="Kind" Type="Edm.String" Nullable="true" />
- <
+ ...
…EntityType> </
Example 24: deletion of a category implies deletion of the related products in that category
EntityType Name="Category">
- <
+ ...
…NavigationProperty Name="Products" Type="Collection(self.Product)">
<OnDelete Action="Cascade">
<Annotation Term="Core.Description"
@@ -1326,13 +1326,13 @@ < </ComplexType>
EntityType Name="Product">
- <
+ ...
…Property Name="ProductDimensions" Type="self.Dimensions" />
<Property Name="ShippingDimensions" Type="self.Dimensions" />
<EntityType>
</
EntityType Name="ShipmentBox">
- <
+ ...
…Property Name="Dimensions" Type="self.Dimensions" />
<EntityType> </
Example 34: the entity container Extending
will contain all child elements that it defines itself, plus all child elements of the Base
entity container located in SomeOtherSchema
EntityContainer Name="Extending" Extends="Some.Other.Schema.Base">
- <
+ ...
…EntityContainer> </
13.2 Entity Set
@@ -1810,7 +1810,7 @@ <Property Name="ID" Nullable="false" Type="Edm.Int32" />
<Property Name="Name" Type="Edm.String" />
<Property Name="Description" Type="Edm.String" />
- ...
+ …
<Annotation Term="UI.DisplayName" Path="Name" />
<Annotation Term="SearchVocabulary.SearchResult">
<Record>
@@ -2412,7 +2412,7 @@ 14.4.1.1 Path
If a path segment is a qualified name, it represents a type cast, and the segment MUST be the name of a type in scope. If the type or instance identified by the preceding path part cannot be cast to the specified type, the path expression evaluates to the null value.
Example 60: type-cast segment
-.../self.Manager/...
+…/self.Manager/…
If a path segment starts with an at (@
) character, it represents a term cast. The at (@
) character MUST be followed by a qualified name that MAY be followed by a hash (#
) character and a simple identifier. The qualified name preceding the hash character MUST resolve to a term that is in scope, the simple identifier following the hash sign is interpreted as a qualifier for the term. If the model element or instance identified by the preceding path part has not been annotated with that term (and if present, with that qualifier), the term cast evaluates to the null value. Four special terms are implicitly “annotated” for media entities and stream properties:
@@ -2423,26 +2423,26 @@ 14.4.1.1 Path
Example 61: term-cast segments
-.../@Capabilities.SortRestrictions/...
+…/@Capabilities.SortRestrictions/…
If a path segment is a simple identifier, it MUST be the name of a child model element of the model element identified by the preceding path part, or a structural or navigation property of the instance identified by the preceding path part. A sequence of navigation segments can traverse multiple CSDL documents. The document containing the path expression only needs to reference the next traversed document to bring the navigation target type into scope, and each traversed document in turn needs to reference only its next document.
A model path MAY contain any number of segments representing collection-valued structural or navigation properties. The result of the expression is the model element reached via this path.
Example 62: property segments in model path
-.../Orders/Items/Product/...
+…/Orders/Items/Product/…
An instance path MUST NOT contain more than one segment representing a collection-valued construct, e.g. an entity set or a collection-valued navigation property that is not followed by a key predicate, or a collection-valued structural property that is not followed by an index segment. The result of the expression is the collection of instances resulting from applying any remaining path segments that operate on a single-valued expression to each instance in the collection-valued segment.
An instance path MAY terminate in a $count
segment if the previous segment is collection-valued, in which case the path evaluates to the number of items in the collection identified by the preceding segment.
Example 63: property segments in instance path
-.../Addresses/Street
-.../Addresses/$count
+…/Addresses/Street
+…/Addresses/$count
A model path MAY contain path segments starting with a navigation property, then followed by an at (@
) character, then followed by the qualified name of a term in scope, and optionally followed by a hash (#
) character and a simple identifier which is interpreted as a qualifier for the term. If the navigation property has not been annotated with that term (and if present, with that qualifier), the path segment evaluates to the null value. This allows addressing annotations on the navigation property itself; annotations on the entity type specified by the navigation property are addressed via a term-cast segment.
Example 64: model path segment addressing an annotation on a navigation property vs. term cast addressing an annotation on the resource addressed by the navigation property
-.../Items@Core.Description
-.../Items/@Core.Description
+…/Items@Core.Description
+…/Items/@Core.Description
An instance path MAY contain path segments starting with an entity set or a collection-valued navigation property, then followed by a key predicate using parentheses-style convention, see OData-URL. The key values are either primitive literals or instance paths. If the key value is a relative instance path, it is interpreted according to the same rule below as the instance path it is part of, not relative to the instance identified by the preceding path part.
@@ -2478,7 +2478,7 @@ 1
EntityType Name="A">
<Property Name="A1" Type="Edm.Boolean" Nullable="false" />
<Property Name="A2" Type="self.B" Nullable="false">
- <Annotation Term="Core.Description" String="...">
+ <Annotation Term="Core.Description" String="…">
<Annotation Term="Core.IsLanguageDependent" Path="A1" />
<Annotation>
</Property>
@@ -2493,7 +2493,7 @@ </1
EntitySet Name="SetA" EntityType="self.A" />
<EntityContainer>
</Annotations Target="self.Container/SetA/A2">
- <Annotation Term="Core.Description" Qualifier="viaset" String="...">
+ <Annotation Term="Core.Description" Qualifier="viaset" String="…">
<Annotation Term="Core.IsLanguageDependent" Path="B1" />
<Annotation>
</Annotations>
@@ -2504,7 +2504,7 @@ </1
Path evaluation for the annotations in the final block starts at the outermost type self.A
named in the target path.
Annotations Target="self.A/A2">
- <Annotation Term="Core.Description" Qualifier="external" String="...">
+ <Annotation Term="Core.Description" Qualifier="external" String="…">
<Annotation Term="Core.IsLanguageDependent" Path="A1" />
<Annotation>
</Annotations>
@@ -3066,11 +3066,11 @@ </15.4 Target Pat
Example 89: Target expressions
-MySchema.MyEntityContainer/MyEntitySet
-MySchema.MyEntityContainer/MySingleton
-MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty
-MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty
-MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp
+MySchema.MyEntityContainer/MyEntitySet
+MySchema.MyEntityContainer/MySingleton
+MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty
+MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty
+MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp
16 CSDL Examples
@@ -3078,153 +3078,153 @@ 16 CSDL Ex
16.1 Products and Categories Example
Example 90:
-edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
- < xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
-edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
- <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
- <Annotation Term="Core.DefaultNamespace" />
- <edmx:Include>
- </edmx:Reference>
- </edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">
- <edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />
- <edmx:Reference>
- </edmx:DataServices>
- <Schema Namespace="ODataDemo">
- <EntityType Name="Product">
- <Key>
- <PropertyRef Name="ID" />
- <Key>
- </Property Name="ID" Type="Edm.Int32" Nullable="false" />
- <Property Name="Description" Type="Edm.String" >
- <Annotation Term="Core.IsLanguageDependent" />
- <Property>
- </Property Name="ReleaseDate" Type="Edm.Date" />
- <Property Name="DiscontinuedDate" Type="Edm.Date" />
- <Property Name="Rating" Type="Edm.Int32" />
- <Property Name="Price" Type="Edm.Decimal" Scale="variable">
- <Annotation Term="Measures.ISOCurrency" Path="Currency" />
- <Property>
- </Property Name="Currency" Type="Edm.String" MaxLength="3" />
- <NavigationProperty Name="Category" Type="ODataDemo.Category"
- < Nullable="false" Partner="Products" />
-NavigationProperty Name="Supplier" Type="ODataDemo.Supplier"
- < Partner="Products" />
-EntityType>
- </EntityType Name="Category">
- <Key>
- <PropertyRef Name="ID" />
- <Key>
- </Property Name="ID" Type="Edm.Int32" Nullable="false" />
- <Property Name="Name" Type="Edm.String" Nullable="false">
- <Annotation Term="Core.IsLanguageDependent" />
- <Property>
- </NavigationProperty Name="Products" Partner="Category"
- < Type="Collection(ODataDemo.Product)">
-OnDelete Action="Cascade" />
- <NavigationProperty>
- </EntityType>
- </EntityType Name="Supplier">
- <Key>
- <PropertyRef Name="ID" />
- <Key>
- </Property Name="ID" Type="Edm.String" Nullable="false" />
- <Property Name="Name" Type="Edm.String" />
- <Property Name="Address" Type="ODataDemo.Address" Nullable="false" />
- <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" />
- <NavigationProperty Name="Products" Partner="Supplier"
- < Type="Collection(ODataDemo.Product)" />
-EntityType>
- </EntityType Name="Country">
- <Key>
- <PropertyRef Name="Code" />
- <Key>
- </Property Name="Code" Type="Edm.String" MaxLength="2"
- < Nullable="false" />
-Property Name="Name" Type="Edm.String" />
- <EntityType>
- </ComplexType Name="Address">
- <Property Name="Street" Type="Edm.String" />
- <Property Name="City" Type="Edm.String" />
- <Property Name="State" Type="Edm.String" />
- <Property Name="ZipCode" Type="Edm.String" />
- <Property Name="CountryName" Type="Edm.String" />
- <NavigationProperty Name="Country" Type="ODataDemo.Country">
- <ReferentialConstraint Property="CountryName"
- < ReferencedProperty="Name" />
-NavigationProperty>
- </ComplexType>
- </Function Name="ProductsByRating">
- <Parameter Name="Rating" Type="Edm.Int32" />
- <ReturnType Type="Collection(ODataDemo.Product)" />
- <Function>
- </EntityContainer Name="DemoService">
- <EntitySet Name="Products" EntityType="ODataDemo.Product">
- <NavigationPropertyBinding Path="Category" Target="Categories" />
- <EntitySet>
- </EntitySet Name="Categories" EntityType="ODataDemo.Category">
- <NavigationPropertyBinding Path="Products" Target="Products" />
- <Annotation Term="Core.Description" String="Product Categories" />
- <EntitySet>
- </EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier">
- <NavigationPropertyBinding Path="Products" Target="Products" />
- <NavigationPropertyBinding Path="Address/Country"
- < Target="Countries" />
-Annotation Term="Core.OptimisticConcurrency">
- <Collection>
- <PropertyPath>Concurrency</PropertyPath>
- <Collection>
- </Annotation>
- </EntitySet>
- </Singleton Name="MainSupplier" Type="ODataDemo.Supplier">
- <NavigationPropertyBinding Path="Products" Target="Products" />
- <Annotation Term="Core.Description" String="Primary Supplier" />
- <Singleton>
- </EntitySet Name="Countries" EntityType="ODataDemo.Country" />
- <FunctionImport Name="ProductsByRating" EntitySet="Products"
- < Function="ODataDemo.ProductsByRating" />
-EntityContainer>
- </Schema>
- </edmx:DataServices>
- </edmx:Edmx> </
+edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
+ < xmlns="http://docs.oasis-open.org/odata/ns/edm" Version="4.0">
+edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
+ <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core">
+ <Annotation Term="Core.DefaultNamespace" />
+ <edmx:Include>
+ </edmx:Reference>
+ </edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Measures.V1.xml">
+ <edmx:Include Alias="Measures" Namespace="Org.OData.Measures.V1" />
+ <edmx:Reference>
+ </edmx:DataServices>
+ <Schema Namespace="ODataDemo">
+ <EntityType Name="Product">
+ <Key>
+ <PropertyRef Name="ID" />
+ <Key>
+ </Property Name="ID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Description" Type="Edm.String" >
+ <Annotation Term="Core.IsLanguageDependent" />
+ <Property>
+ </Property Name="ReleaseDate" Type="Edm.Date" />
+ <Property Name="DiscontinuedDate" Type="Edm.Date" />
+ <Property Name="Rating" Type="Edm.Int32" />
+ <Property Name="Price" Type="Edm.Decimal" Scale="variable">
+ <Annotation Term="Measures.ISOCurrency" Path="Currency" />
+ <Property>
+ </Property Name="Currency" Type="Edm.String" MaxLength="3" />
+ <NavigationProperty Name="Category" Type="ODataDemo.Category"
+ < Nullable="false" Partner="Products" />
+NavigationProperty Name="Supplier" Type="ODataDemo.Supplier"
+ < Partner="Products" />
+EntityType>
+ </EntityType Name="Category">
+ <Key>
+ <PropertyRef Name="ID" />
+ <Key>
+ </Property Name="ID" Type="Edm.Int32" Nullable="false" />
+ <Property Name="Name" Type="Edm.String" Nullable="false">
+ <Annotation Term="Core.IsLanguageDependent" />
+ <Property>
+ </NavigationProperty Name="Products" Partner="Category"
+ < Type="Collection(ODataDemo.Product)">
+OnDelete Action="Cascade" />
+ <NavigationProperty>
+ </EntityType>
+ </EntityType Name="Supplier">
+ <Key>
+ <PropertyRef Name="ID" />
+ <Key>
+ </Property Name="ID" Type="Edm.String" Nullable="false" />
+ <Property Name="Name" Type="Edm.String" />
+ <Property Name="Address" Type="ODataDemo.Address" Nullable="false" />
+ <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" />
+ <NavigationProperty Name="Products" Partner="Supplier"
+ < Type="Collection(ODataDemo.Product)" />
+EntityType>
+ </EntityType Name="Country">
+ <Key>
+ <PropertyRef Name="Code" />
+ <Key>
+ </Property Name="Code" Type="Edm.String" MaxLength="2"
+ < Nullable="false" />
+Property Name="Name" Type="Edm.String" />
+ <EntityType>
+ </ComplexType Name="Address">
+ <Property Name="Street" Type="Edm.String" />
+ <Property Name="City" Type="Edm.String" />
+ <Property Name="State" Type="Edm.String" />
+ <Property Name="ZipCode" Type="Edm.String" />
+ <Property Name="CountryName" Type="Edm.String" />
+ <NavigationProperty Name="Country" Type="ODataDemo.Country">
+ <ReferentialConstraint Property="CountryName"
+ < ReferencedProperty="Name" />
+NavigationProperty>
+ </ComplexType>
+ </Function Name="ProductsByRating">
+ <Parameter Name="Rating" Type="Edm.Int32" />
+ <ReturnType Type="Collection(ODataDemo.Product)" />
+ <Function>
+ </EntityContainer Name="DemoService">
+ <EntitySet Name="Products" EntityType="ODataDemo.Product">
+ <NavigationPropertyBinding Path="Category" Target="Categories" />
+ <EntitySet>
+ </EntitySet Name="Categories" EntityType="ODataDemo.Category">
+ <NavigationPropertyBinding Path="Products" Target="Products" />
+ <Annotation Term="Core.Description" String="Product Categories" />
+ <EntitySet>
+ </EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier">
+ <NavigationPropertyBinding Path="Products" Target="Products" />
+ <NavigationPropertyBinding Path="Address/Country"
+ < Target="Countries" />
+Annotation Term="Core.OptimisticConcurrency">
+ <Collection>
+ <PropertyPath>Concurrency</PropertyPath>
+ <Collection>
+ </Annotation>
+ </EntitySet>
+ </Singleton Name="MainSupplier" Type="ODataDemo.Supplier">
+ <NavigationPropertyBinding Path="Products" Target="Products" />
+ <Annotation Term="Core.Description" String="Primary Supplier" />
+ <Singleton>
+ </EntitySet Name="Countries" EntityType="ODataDemo.Country" />
+ <FunctionImport Name="ProductsByRating" EntitySet="Products"
+ < Function="ODataDemo.ProductsByRating" />
+EntityContainer>
+ </Schema>
+ </edmx:DataServices>
+ </edmx:Edmx> </
16.2 Annotations for Products and Categories Example
Example 91:
-edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
- < Version="4.01">
-edmx:Reference Uri="http://host/service/$metadata">
- <edmx:Include Namespace="ODataDemo" Alias="target" />
- <edmx:Reference>
- </edmx:Reference Uri="http://somewhere/Vocabulary/V1">
- <edmx:Include Alias="Vocabulary1" Namespace="Some.Vocabulary.V1" />
- <edmx:Reference>
- </edmx:DataServices>
- <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
- < Namespace="External.Annotations">
-Annotations Target="ODataDemo.Supplier">
- <Annotation Term="Vocabulary1.EMail">
- <Null />
- <Annotation>
- </Annotation Term="Vocabulary1.AccountID" Path="ID" />
- <Annotation Term="Vocabulary1.Title" String="Supplier Info" />
- <Annotation Term="Vocabulary1.DisplayName">
- <Apply Function="odata.concat">
- <Path>Name</Path>
- <String> in </String>
- <Path>Address/CountryName</Path>
- <Apply>
- </Annotation>
- </Annotations>
- </Annotations Target="ODataDemo.Product">
- <Annotation Term="Vocabulary1.Tags">
- <Collection>
- <String>MasterData</String>
- <Collection>
- </Annotation>
- </Annotations>
- </Schema>
- </edmx:DataServices>
- </edmx:Edmx> </
+edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
+ < Version="4.01">
+edmx:Reference Uri="http://host/service/$metadata">
+ <edmx:Include Namespace="ODataDemo" Alias="target" />
+ <edmx:Reference>
+ </edmx:Reference Uri="http://somewhere/Vocabulary/V1">
+ <edmx:Include Alias="Vocabulary1" Namespace="Some.Vocabulary.V1" />
+ <edmx:Reference>
+ </edmx:DataServices>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
+ < Namespace="External.Annotations">
+Annotations Target="ODataDemo.Supplier">
+ <Annotation Term="Vocabulary1.EMail">
+ <Null />
+ <Annotation>
+ </Annotation Term="Vocabulary1.AccountID" Path="ID" />
+ <Annotation Term="Vocabulary1.Title" String="Supplier Info" />
+ <Annotation Term="Vocabulary1.DisplayName">
+ <Apply Function="odata.concat">
+ <Path>Name</Path>
+ <String> in </String>
+ <Path>Address/CountryName</Path>
+ <Apply>
+ </Annotation>
+ </Annotations>
+ </Annotations Target="ODataDemo.Product">
+ <Annotation Term="Vocabulary1.Tags">
+ <Collection>
+ <String>MasterData</String>
+ <Collection>
+ </Annotation>
+ </Annotations>
+ </Schema>
+ </edmx:DataServices>
+ </edmx:Edmx> </
17 Conformance
diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md
index d3587a01e..dd2ecb0b0 100644
--- a/docs/odata-csdl-xml/odata-csdl-xml.md
+++ b/docs/odata-csdl-xml/odata-csdl-xml.md
@@ -867,7 +867,7 @@ Example 7:
- ...
+ …
```
@@ -931,16 +931,16 @@ Example 8: references to other CSDL documents
Version="4.0">
- ...
+ …
- ...
+ …
- ...
+ …
- ...
+ …
```
:::
@@ -1024,7 +1024,7 @@ vocabulary terms
- ...
+ …
```
:::
@@ -1111,7 +1111,7 @@ Example 10: reference documents that contain annotations
Qualifier="Tablet"
TargetNamespace="com.example.Person" />
- ...
+ …
```
:::
@@ -1216,7 +1216,7 @@ schema
```xml
- ...
+ …
```
:::
@@ -1249,7 +1249,7 @@ Example 12: annotations should only be applied to tablet devices
```xml
- ...
+ …
```
:::
@@ -1787,14 +1787,14 @@ Example 22: the Product entity type has a navigation property to a
Category, which has a navigation link back to one or more products
```xml
- ...
+ …
- ...
+ …
@@ -2033,7 +2033,7 @@ category, and the `CategoryKind` property of the product is identical to
the `Kind` property of the category.
```xml
- ...
+ …
@@ -2051,7 +2051,7 @@ the `Kind` property of the category.
- ...
+ …
```
:::
@@ -2100,7 +2100,7 @@ Example 24: deletion of a category implies deletion of the related
products in that category
```xml
- ...
+ …
- ...
+ …
- ...
+ …
```
@@ -2948,7 +2948,7 @@ elements that it defines itself, plus all child elements of the `Base`
entity container located in `SomeOtherSchema`
```xml
- ...
+ …
```
:::
@@ -3329,7 +3329,7 @@ type specified by the term `SearchResult`
- ...
+ …
@@ -4109,7 +4109,7 @@ the null value.
::: example
Example 60: type-cast segment
```
-.../self.Manager/...
+…/self.Manager/…
```
:::
@@ -4134,7 +4134,7 @@ properties:
::: example
Example 61: term-cast segments
```
-.../@Capabilities.SortRestrictions/...
+…/@Capabilities.SortRestrictions/…
```
:::
@@ -4154,7 +4154,7 @@ expression is the model element reached via this path.
::: example
Example 62: property segments in model path
```
-.../Orders/Items/Product/...
+…/Orders/Items/Product/…
```
:::
@@ -4174,11 +4174,11 @@ number of items in the collection identified by the preceding segment.
::: example
Example 63: property segments in instance path
```
-.../Addresses/Street
+…/Addresses/Street
```
```
-.../Addresses/$count
+…/Addresses/$count
```
:::
@@ -4198,11 +4198,11 @@ segment](#TermCast).
Example 64: model path segment addressing an annotation on a navigation property
vs. term cast addressing an annotation on the resource addressed by the navigation property
```
-.../Items@Core.Description
+…/Items@Core.Description
```
```
-.../Items/@Core.Description
+…/Items/@Core.Description
```
:::
@@ -4325,7 +4325,7 @@ enclosing type `self.A` of the hosting property `A2`.
-
+
@@ -4345,7 +4345,7 @@ type `self.B` of the hosting property `A2`.
-
+
@@ -4361,7 +4361,7 @@ type `self.A` named in the target path.
:::: varxml
```xml
-
+
@@ -5357,9 +5357,21 @@ segments
Example 89: Target expressions
```
MySchema.MyEntityContainer/MyEntitySet
+```
+
+```
MySchema.MyEntityContainer/MySingleton
+```
+
+```
MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty
+```
+
+```
MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty
+```
+
+```
MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp
```
:::
diff --git a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.html b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.html
index 308d7e60b..d9b2b34ef 100644
--- a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.html
+++ b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.html
@@ -1928,22 +1928,22 @@ { "Customer": { "Country": "USA", "Name": "Joe" },
"Product": { "Category": { "Name": "Non-Food" }, "Name": "Paper" },
"Total@type": "Decimal", "Total": 1 },
- ...
+…
plus additional fifteen rollup entities for subtotals: five without customer name
{ "Customer": { "Country": "USA" },
"Product": { "Category": { "Name": "Food" }, "Name": "Sugar" },
"Total@type": "Decimal", "Total": 2 },
- ...
+…
six without product name
{ "Customer": { "Country": "USA", "Name": "Joe" },
"Product": { "Category": { "Name": "Food" } },
"Total@type": "Decimal", "Total": 6 },
- ...
+ …
and four with neither customer nor product name
{ "Customer": { "Country": "USA" },
"Product": { "Category": { "Name": "Food" } },
"Total@type": "Decimal", "Total": 14 },
- ...
+ …
]
}
<EntityContainer Name="SalesData">
<Annotation Term="Aggregation.ApplySupportedDefaults" />
- ...
+ …
</EntityContainer>
Example 50: Define aggregation support only for the products of a given category
Annotations Target="SalesModel.SalesData/Categories/Products">
<Annotation Term="Aggregation.ApplySupported">
- <
+ ...
…Annotation>
</Annotations> </
{
"@context": "$metadata#SalesOrganizations",
"value": [
- ...
+ …
{ "ID": "Atlantis", "Name": "Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy":
[ "US", "Sales" ] },
{ "ID": "AtlantisChild", "Name": "Child of Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy":
[ "Atlantis", "US", "Sales" ] },
- ...
+ …
{ "ID": "Atlantis", "Name": "Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy":
[ "EMEA", "Sales" ] },
{ "ID": "AtlantisChild", "Name": "Child of Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy":
[ "Atlantis", "EMEA", "Sales" ] },
- ...
+ …
]
}
@@ -3073,7 +3073,7 @@ {
"@context": "$metadata#Sales(Customer(Country),Total)",
"value": [
- { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Coffee" },
+ { "Customer": { "Country": "USA" }, "Product": { "Name": "Coffee" },
"Total@type": "Decimal", "Total": 12
},
- { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Paper" },
+ { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Paper" },
"Total@type": "Decimal", "Total": 3
},
- { "Customer":{ "Country": "USA" },
+ { "Customer": { "Country": "USA" },
"Total@type": "Decimal", "Total": 19
},
- { "Customer":{ "Country": "Netherlands" },
+ { "Customer": { "Country": "Netherlands" },
"Total@type": "Decimal", "Total": 5
}
]
@@ -3736,19 +3736,19 @@ {
"@context": "$metadata#Sales(Customer(Country),Product(Name),Total)",
"value": [
- { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Paper" },
+ { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Paper" },
"Total@type": "Decimal", "Total": 3
},
- { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Sugar" },
+ { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Sugar" },
"Total@type": "Decimal", "Total": 2
},
- { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Sugar" },
+ { "Customer": { "Country": "USA" }, "Product": { "Name": "Sugar" },
"Total@type": "Decimal", "Total": 2
},
- { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Coffee" },
+ { "Customer": { "Country": "USA" }, "Product": { "Name": "Coffee" },
"Total@type": "Decimal", "Total": 12
},
- { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Paper" },
+ { "Customer": { "Country": "USA" }, "Product": { "Name": "Paper" },
"Total@type": "Decimal", "Total": 5
}
]
@@ -4312,14 +4312,14 @@ { "SalesOrganization": { "ID": "Atlantis", "Name": "Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy": [ "US", "Sales" ] },
"MultiParentWeightedTotal": 6 },
- ...
+ …
{ "SalesOrganization": { "ID": "EMEA", "Name": "EMEA",
"@Aggregation.UpPath#MultiParentHierarchy": [ "Sales" ] },
"MultiParentWeightedTotal": 9 },
{ "SalesOrganization": { "ID": "Atlantis", "Name": "Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy": [ "EMEA", "Sales" ] },
"MultiParentWeightedTotal": 4 },
- ...
+ …
]
}
@@ -4376,7 +4376,7 @@ "TotalPopulation@type": "Int32", "TotalPopulation": 1412000000 },
{ "Continent": { "Name": "Asia" }, "Country": { "Name": "India" },
"TotalPopulation@type": "Int32", "TotalPopulation": 1408000000 },
- ...
+ …
]
}
diff --git a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md
index fc49e8686..b56cf4e2b 100644
--- a/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md
+++ b/docs/odata-data-aggregation-ext/odata-data-aggregation-ext.md
@@ -885,7 +885,7 @@ Date|Month|Quarter|Year
2022-01-01|2022-01|2022-1|2022
2022-04-01|2022-04|2022-2|2022
2022-04-10|2022-04|2022-2|2022
-...|||
+…|||
:::::
::::: {style=top:150px;left:360px}
@@ -1580,28 +1580,28 @@ results in seven entities for the finest grouping level
{ "Customer": { "Country": "USA", "Name": "Joe" },
"Product": { "Category": { "Name": "Non-Food" }, "Name": "Paper" },
"Total@type": "Decimal", "Total": 1 },
- ...
+ …
```
plus additional fifteen rollup entities for subtotals: five without customer name
```json
{ "Customer": { "Country": "USA" },
"Product": { "Category": { "Name": "Food" }, "Name": "Sugar" },
"Total@type": "Decimal", "Total": 2 },
- ...
+ …
```
six without product name
```json
{ "Customer": { "Country": "USA", "Name": "Joe" },
"Product": { "Category": { "Name": "Food" } },
"Total@type": "Decimal", "Total": 6 },
- ...
+ …
```
and four with neither customer nor product name
```json
{ "Customer": { "Country": "USA" },
"Product": { "Category": { "Name": "Food" } },
"Total@type": "Decimal", "Total": 14 },
- ...
+ …
]
}
```
@@ -2235,7 +2235,7 @@ results in
"value": [
{ "Products": { "Name": "Paper" }, "Sales": { "Amount": 1 } },
{ "Products": { "Name": "Sugar" }, "Sales": { "Amount": 2 } },
- ...
+ …
]
}
```
@@ -2295,7 +2295,7 @@ Example 49: an entity container with default support for everything defined in t
```xml
Example 2:
{
"@context": "http://host/service/$metadata#Customers/$entity",
- ...
+ …
"@editLink": "Customers('ALFKI')",
- ...
+ …
"Orders@navigationLink": "Customers('ALFKI')/Orders",
- ...
+ …
}
The resulting absolute URLs are http://host/service/Customers('ALFKI')
and http://host/service/Customers('ALFKI')/Orders
.
{
"@context": "http://host/service/$metadata#Customers/$entity",
"@metadataEtag": "W/\"A1FF3E230954908F\"",
- ...
+ …
}
metadataEtag
(odata.metadataEtag
)count
(odata.count
)removed
(odata.removed
)Example 13:
{
"@context": "http://host/service/$metadata#Customers/$entity",
- ...
+ …
"Address": {
"Street": "Obere Str. 57",
"City": "Berlin",
@@ -790,12 +790,12 @@ Example 14: partial collection of strings with next link
{
"@context": "http://host/service/$metadata#Customers/$entity",
- ...
+ …
"EmailAddresses": [
"Julie@Swansworth.com",
"Julie.Swansworth@work.com"
],
- "EmailAddresses@nextLink": "..."
+ "EmailAddresses@nextLink": "…"
}
A collection of primitive values that occurs in a property of type Edm.Untyped
is interpreted as a collection of Edm.Boolean
, Edm.String
, and Edm.Decimal
values, depending on the JavaScript type.
Example 16:
{
"@context": "http://host/service/$metadata#Customers/$entity",
- ...
+ …
"Orders@navigationLink": "Customers('ALFKI')/Orders",
- ...
+ …
}
Example 17:
{
"@context": "http://host/service/$metadata#Customers/$entity",
- ...
+ …
"Orders@associationLink": "Customers('ALFKI')/Orders/$ref",
- ...
+ …
}
{
"@context": "http://host/service/$metadata#Customers/$entity",
"Orders@count": 42,
- "Orders": [ ... ],
- "Orders@nextLink": "...",
- ...
+ "Orders": [ … ],
+ "Orders@nextLink": "…",
+ …
}
{
"ID": 11643,
"Amount": 100,
- ...,
+ …,
"Customer": {
"ID": "ANEWONE",
- ...
+ …
},
"Items": [
{
"Product": { "@id": "Products(28)" },
"Quantity": 1,
- ...
+ …
},
{
"Product": { "@id": "Products(39)" },
"Quantity": 5,
- ...
+ …
}
]
}
Note: the collection ETag for a navigation property may or may not be identical to the ETag of the containing entity, the example shows a different ETag for the Items
collection.
Example 24:
{
"@context": "http://host/service/$metadata#Products/$entity",
- ...
+ …
"Thumbnail@mediaReadLink": "http://server/Thumbnail546.jpg",
"Thumbnail@mediaEditLink": "http://server/uploads/Thumbnail546.jpg",
"Thumbnail@mediaContentType": "image/jpeg",
"Thumbnail@mediaEtag": "W/\"####\"",
- "Thumbnail": "...base64url encoded value...",
- ...
+ "Thumbnail": "…base64url encoded value…",
+ …
}
Example 30: empty collection of complex values
{
-"@context":"http://host/service/$metadata#Collection(Model.Address)",
+ "@context": "http://host/service/$metadata#Collection(Model.Address)",
"value": []
}
Example 28:
{
-"@context": "...",
+ "@context": "…",
"@count": 37,
"value": [
- { ... },
- { ... },
- { ... }
+ { … },
+ { … },
+ { … }
],
- "@nextLink": "...?$skiptoken=342r89"
+ "@nextLink": "…?$skiptoken=342r89"
}
Example 36: deleted entity in OData 4.0 response — note that id
is a property, not control information
{
-"@context":"#Customers/$deletedEntity",
- "reason":"deleted",
- "id":"Customers('ANTON')"
+ "@context": "#Customers/$deletedEntity",
+ "reason": "deleted",
+ "id": "Customers('ANTON')"
}
In OData 4.01 payloads the deleted-entity object MUST include the following properties, regardless of the specified metadata
value:
Example 37: deleted entity in OData 4.01 response with id
control information (prefixed with an @
)
{
-"@context":"#Customers/$deletedEntity",
- "@removed":{
- "reason":"deleted",
- "@myannoation.deletedBy":"Mario"
+ "@context": "#Customers/$deletedEntity",
+ "@removed": {
+ "reason": "deleted",
+ "@myannoation.deletedBy": "Mario"
},
- "@id":"Customers('ANTON')"
+ "@id": "Customers('ANTON')"
}
Example 38: entity removed OData 4.01 response without id
control information and instead all key fields (ID
is the single key field of Customer
)
{
-"@removed":{},
- "ID":"ANTON"
+ "@removed": {},
+ "ID": "ANTON"
}
{
"@context": "http://host/service/$metadata#Employees/$entity",
"#Model.RemainingVacation": {},
- ...
+ …
}
{
"@context": "http://host/service/$metadata#LeaveRequests/$entity",
"#Model.Approve": {},
- ...
+ …
}
Client makes a GET
request to the next link and receives a 202
response with the location of a new monitor resource.
HTTP/1.1 202 Accepted
@@ -1988,8 +1988,8 @@ 21.1 E
}
],
"innererror": {
- "trace": [...],
- "context": {...}
+ "trace": […],
+ "context": {…}
}
}
}
10.20 $crossjoin
Response
Context URL template:
{context-url}#Collection(Edm.ComplexType)
-Responses to requests to the virtual collections $crossjoin(...)
(see OData-URL) use the built-in abstract complex type. Single instances in these responses do not have a context URL.
Responses to requests to the virtual collections $crossjoin(…)
(see OData-URL) use the built-in abstract complex type. Single instances in these responses do not have a context URL.
This chapter describes the semantics of the HTTP verbs GET
, POST
, PATCH
, PUT
, and DELETE
for OData resources.
Example 76: using the JSON format, 4.0 clients can create a new manager entity with links to an existing manager (of managers) and to two existing employees by applying the odata.bind
annotation to the Manager
and DirectReports
navigation properties
{
- "@odata.type":"#Northwind.Manager",
+ "@odata.type": "#Northwind.Manager",
"ID": 1,
"FirstName": "Pat",
"LastName": "Griswold",
@@ -1784,7 +1784,7 @@
Example 77: using the JSON format, 4.01 clients can create a new manager entity with links to an existing manager (of managers) and to two existing employees by including the entity-ids within the Manager
and DirectReports
navigation properties
{
- "@type":"#Northwind.Manager",
+ "@type": "#Northwind.Manager",
"ID": 1,
"FirstName": "Pat",
"LastName": "Griswold",
@@ -1827,7 +1827,7 @@
Example 78: using the JSON format, a 4.01 PATCH
request can update a manager entity. Following the update, the manager has three direct reports; two existing employees and one new employee named Suzanne Brown
. The LastName
of employee 6 is updated to Smith
.
{
- "@type":"#Northwind.Manager",
+ "@type": "#Northwind.Manager",
"FirstName" : "Patricia",
"DirectReports": [
{
@@ -1946,10 +1946,10 @@ would only include control information for the stream property, not the stream data itself
{
"@context": "http://host/service/$metadata#Products/$entity",
- ...
+ …
"Thumbnail@mediaReadLink": "http://server/Thumbnail546.jpg",
"Thumbnail@mediaEditLink": "http://server/uploads/Thumbnail546.jpg",
- ...
+ …
}
The stream data can then be requested using the media read link:
GET http://server/Thumbnail546.jpg
@@ -2044,13 +2044,12 @@ updated using PATCH
semantics. Structured types MAY include nested collections or delta collections, in which case the semantics described in Update a Collection of Entities applies.
Example 84: change the color of all beige-brown products
-PATCH /service/Products/$filter(@bar)/$each?@bar=Color eq
-'beige-brown'
-Content-Type: application/json
-
-{
- "Color": "taupe"
-}
+PATCH /service/Products/$filter(@bar)/$each?@bar=Color eq 'beige-brown'
+Content-Type: application/json
+
+{
+ "Color": "taupe"
+}
The response, if requested, is a collection payload containing the updated representation of each member identified by the request. If the update payload includes nested collections or nested delta collections, then they MUST be included in the response, as described in Update a Collection of Entities.
Clients should note that requesting a response may be expensive for services that could otherwise efficiently apply updates to a (possibly filtered) collection.
@@ -2109,14 +2108,14 @@
Example 91: given a GET
request to http://host/service/Customers('ALFKI')
, the service might respond with a Customer that includes the SampleEntities.MostRecentOrder
function bound to the entity
{
- "@context": ...,
+ "@context": …,
"CustomerID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"#SampleEntities.MostRecentOrder": {
"title": "Most Recent Order",
"target": "Customers('ALFKI')/SampleEntities.MostRecentOrder()"
},
- ...
+ …
}
An efficient format that assumes client knowledge of metadata may omit actions and functions from the payload whose target URL can be computed via metadata following standard conventions defined in OData-URL.
@@ -2124,11 +2123,11 @@
Example 92: the SampleEntities.MostRecentOrder
function is not available for customer ALFKI
{
- "@context": ...,
+ "@context": …,
"CustomerID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"#SampleEntities.MostRecentOrder": null,
- ...
+ …
}
11.5.4 Functions
@@ -2144,7 +2143,7 @@ requesting stream properties.
Parameter values passed to functions MUST be specified either as a URL literal (for primitive values) or as a JSON formatted OData object (for complex values, or collections of primitive or complex values). Entity typed values are passed as JSON formatted entities that MAY include a subset of the properties, or just the entity reference, as appropriate to the function.
@@ -2297,11 +2296,11 @@
Example 102:
-PATCH /path/service/People(1) HTTP/1.1
-Host: myserver.mydomain.org:1234
-Content-Type: application/json
-
-{"Name": "Peter"}
+PATCH /path/service/People(1) HTTP/1.1
+Host: myserver.mydomain.org:1234
+Content-Type: application/json
+
+{"Name": "Peter"}
- Resource path relative to the batch request URI.
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md
index 11dba34ab..d2511615a 100644
--- a/docs/odata-protocol/odata-protocol.md
+++ b/docs/odata-protocol/odata-protocol.md
@@ -2529,7 +2529,7 @@ Context URL template:
{context-url}#Collection(Edm.ComplexType)
-Responses to requests to the virtual collections `$crossjoin(...)` (see
+Responses to requests to the virtual collections `$crossjoin(…)` (see
[OData-URL](#ODataURL)) use the built-in abstract complex type. Single
instances in these responses do not have a context URL.
@@ -4181,7 +4181,7 @@ entity with links to an existing manager (of managers) and to two existing emplo
annotation to the `Manager` and `DirectReports` navigation properties
```json
{
- "@odata.type":"#Northwind.Manager",
+ "@odata.type": "#Northwind.Manager",
"ID": 1,
"FirstName": "Pat",
"LastName": "Griswold",
@@ -4200,7 +4200,7 @@ entity with links to an existing manager (of managers) and to two existing emplo
within the `Manager` and `DirectReports` navigation properties
```json
{
- "@type":"#Northwind.Manager",
+ "@type": "#Northwind.Manager",
"ID": 1,
"FirstName": "Pat",
"LastName": "Griswold",
@@ -4398,7 +4398,7 @@ reports; two existing employees and one new employee named
`Suzanne Brown`. The `LastName` of employee 6 is updated to `Smith`.
```json
{
- "@type":"#Northwind.Manager",
+ "@type": "#Northwind.Manager",
"FirstName" : "Patricia",
"DirectReports": [
{
@@ -4713,10 +4713,10 @@ would only include control information for the stream property, not the stream d
```json
{
"@context": "http://host/service/$metadata#Products/$entity",
- ...
+ …
"Thumbnail@mediaReadLink": "http://server/Thumbnail546.jpg",
"Thumbnail@mediaEditLink": "http://server/uploads/Thumbnail546.jpg",
- ...
+ …
}
```
The stream data can then be requested using the media read link:
@@ -5054,8 +5054,7 @@ Entities](#UpdateaCollectionofEntities) applies.
::: example
Example 84: change the color of all beige-brown products
```json
-PATCH /service/Products/$filter(@bar)/$each?@bar=Color eq
-'beige-brown'
+PATCH /service/Products/$filter(@bar)/$each?@bar=Color eq 'beige-brown'
Content-Type: application/json
{
@@ -5235,14 +5234,14 @@ a Customer that includes the `SampleEntities.MostRecentOrder` function
bound to the entity
```json
{
- "@context": ...,
+ "@context": …,
"CustomerID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"#SampleEntities.MostRecentOrder": {
"title": "Most Recent Order",
"target": "Customers('ALFKI')/SampleEntities.MostRecentOrder()"
},
- ...
+ …
}
```
:::
@@ -5260,11 +5259,11 @@ Example 92: the `SampleEntities.MostRecentOrder` function is not
available for customer `ALFKI`
```json
{
- "@context": ...,
+ "@context": …,
"CustomerID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"#SampleEntities.MostRecentOrder": null,
- ...
+ …
}
```
:::
@@ -5338,7 +5337,7 @@ returned by the composable `MyShoppingCart` function import
```
POST http://host/service/MyShoppingCart()/Items
-...
+…
```
:::
@@ -5870,7 +5869,7 @@ GET https://host:1234/path/service/People(1) HTTP/1.1
::: example
Example 102:
-```
+```json
PATCH /path/service/People(1) HTTP/1.1
Host: myserver.mydomain.org:1234
Content-Type: application/json
diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html
index b197af820..ac8094874 100644
--- a/docs/odata-url-conventions/odata-url-conventions.html
+++ b/docs/odata-url-conventions/odata-url-conventions.html
@@ -426,21 +426,16 @@ 2.2 URL Syntax<
For example, one of these rules is that single quotes within string literals are represented as two consecutive single quotes.
Example 3: valid OData URLs:
-http://host/service/People('O''Neil')
-
-http://host/service/People(%27O%27%27Neil%27)
-
-http://host/service/People%28%27O%27%27Neil%27%29
-
-http://host/service/Categories('Smartphone%2FTablet')
+http://host/service/People('O''Neil')
+http://host/service/People(%27O%27%27Neil%27)
+http://host/service/People%28%27O%27%27Neil%27%29
+http://host/service/Categories('Smartphone%2FTablet')
Example 4: invalid OData URLs:
-http://host/service/People('O'Neil')
-
-http://host/service/People('O%27Neil')
-
-http://host/service/Categories('Smartphone/Tablet')
+http://host/service/People('O'Neil')
+http://host/service/People('O%27Neil')
+http://host/service/Categories('Smartphone/Tablet')
The first and second examples are invalid because a single quote in a string literal must be represented as two consecutive single quotes. The third example is invalid because forward slashes are interpreted as path segment separators and Categories('Smartphone
is not a valid OData path segment, nor is Tablet')
.
@@ -621,34 +616,26 @@ 4.3.5
In addition to the canonical (primary) key an entity set or entity type can specify one or more alternate keys with the Core.AlternateKeys
term (see OData-VocCore). Entities can be addressed via an alternate key using the same parentheses-style convention as for the canonical key, with one difference: single-part alternate keys MUST specify the key property name to unambiguously determine the alternate key.
Example 24: the same employee identified via the alternate key SSN, the canonical (primary) key ID using the non-canonical long form with specified key property name, and the canonical short form without key property name
-http://host/service/Employees(SSN='123-45-6789')
-
-http://host/service/Employees(ID='A1245')
-
-http://host/service/Employees('A1245')
+http://host/service/Employees(SSN='123-45-6789')
+http://host/service/Employees(ID='A1245')
+http://host/service/Employees('A1245')
4.3.6 Key-as-Segment Convention
Services MAY support an alternate convention for addressing entities by appending a segment containing the unprefixed and unquoted key value to the URL of the collection containing the entity. Forward-slashes in key value segments MUST be percent-encoded; single quotes within key value segments are treated as part of the key value and do not need to be doubled or percent encoded.
Example 25: valid OData URLs:
-http://host/service/Employees/A1245
-
-http://host/service/People/O'Neil
-
-http://host/service/People/O%27Neil
-
-http://host/service/Categories/Smartphone%2FTablet
-
-http://host/service/ThingyWithDurationKey/P12DT23H59M59.999999999999S
-
-http://host/service/ThingyWithEnumerationKey/Yellow
+http://host/service/Employees/A1245
+http://host/service/People/O'Neil
+http://host/service/People/O%27Neil
+http://host/service/Categories/Smartphone%2FTablet
+http://host/service/ThingyWithDurationKey/P12DT23H59M59.999999999999S
+http://host/service/ThingyWithEnumerationKey/Yellow
For multi-part keys, the entity MUST be addressed by multiple segments applied, one for each key value, in the order they appear in the metadata description of the entity key.
Example 26: multi-part key predicate, parentheses-style and key-as-segment
-https://host/service/OrderItems(OrderID=1,ItemNo=2)
-
-https://host/service/OrderItems/1/2
+https://host/service/OrderItems(OrderID=1,ItemNo=2)
+https://host/service/OrderItems/1/2
If a navigation property leading to a related entity type has a partner navigation property that specifies a referential constraint, then those key properties of the related entity that take part in the referential constraint MUST be omitted from URLs using key-as-segment convention.
@@ -676,11 +663,9 @@ OData-Protocol.
Example 29: three ways of unrelating Categories(1)
and Products(0)
; the second option is supported only in OData 4.01
-DELETE http://host/service/Categories(1)/Products/$ref?$id=../../Products(0)
-
-DELETE http://host/service/Categories(1)/Products(0)/$ref
-
-DELETE http://host/service/Products(0)/Category/$ref
+DELETE http://host/service/Categories(1)/Products/$ref?$id=../../Products(0)
+DELETE http://host/service/Categories(1)/Products(0)/$ref
+DELETE http://host/service/Products(0)/Category/$ref
4.5 Addressing Operations
The semantic rules for addressing and invoking actions and functions are defined in the OData-Protocol document.
@@ -753,9 +738,8 @@
Example 37: entity restricted to a VipCustomer
instance, resulting in 404 Not Found
if the customer with key 1
is not a VipCustomer
-http://host/service/Customers/Model.VipCustomer(1)
-
-http://host/service/Customers(1)/Model.VipCustomer
+http://host/service/Customers/Model.VipCustomer(1)
+http://host/service/Customers(1)/Model.VipCustomer
Example 38: cast the complex property Address
to its derived type DetailedAddress
, then get a property of the derived type
@@ -809,26 +793,26 @@ $count
, $skip
, and $top
query options can also be used with no special semantics.
Example 46: if Sales
had a structural property ProductID
instead of a navigation property Product
, a “cross join” between Sales
and Products
could be addressed
-http://host/service/$crossjoin(Products,Sales)?$filter=Products/ID eq Sales/ProductID
+http://host/service/$crossjoin(Products,Sales)?$filter=Products/ID eq Sales/ProductID
and would result in
-{
-"@odata.context":"http://host/service/$metadata#Collection(Edm.ComplexType)",
- "value":[
- {
- "Products@odata.navigationLink":"Products(0)",
- "Sales@odata.navigationLink":"Sales(42)",
- },
- {
- "Products@odata.navigationLink":"Products(0)",
- "Sales@odata.navigationLink":"Sales(57)",
- },
- ...
- {
- "Products@odata.navigationLink":"Products(99)",
- "Sales@odata.navigationLink":"Sales(21)",
- }
- ]
- }
+{
+"@odata.context": "http://host/service/$metadata#Collection(Edm.ComplexType)",
+ "value": [
+ {
+ "Products@odata.navigationLink": "Products(0)",
+ "Sales@odata.navigationLink": "Sales(42)",
+ },
+ {
+ "Products@odata.navigationLink": "Products(0)",
+ "Sales@odata.navigationLink": "Sales(57)",
+ },
+ …
+ {
+ "Products@odata.navigationLink": "Products(99)",
+ "Sales@odata.navigationLink": "Sales(21)",
+ }
+ ]
+ }
4.16 Addressing All Entities in a Service
The symbolic resource $all
, located at the service root, identifies the collection of all entities in a service, i.e. the union of all entity sets plus all singletons.
@@ -1161,15 +1145,11 @@ 5.1.1.6.1 h
The hassubset
function returns true if the first collection can be transformed into the second collection by reordering and/or removing zero or more items. The hasSubsetMethodCallExpr
syntax rule defines how the hassubset
function is invoked.
Example 77: hassubset
expressions that return true
-hassubset([4,1,3],[4,1,3])
-
-hassubset([4,1,3],[1,3,4])
-
-hassubset([4,1,3],[3,1])
-
-hassubset([4,1,3],[4,3])
-
-hassubset([4,1,3,1],[1,1])
+hassubset([4,1,3],[4,1,3])
+hassubset([4,1,3],[1,3,4])
+hassubset([4,1,3],[3,1])
+hassubset([4,1,3],[4,3])
+hassubset([4,1,3,1],[1,1])
Example 78: hassubset
expression that returns false: 1 appears only once in the left operand
@@ -1181,21 +1161,16 @@ 5.
The hassubsequence
function returns true if the first collection can be transformed into the second collection by removing zero or more items. The hasSubsequenceMethodCallExpr
syntax rule defines how the hassubsequence
function is invoked.
Example 79: hassubsequence
expressions that return true
-hassubsequence([4,1,3],[4,1,3])
-
-hassubsequence([4,1,3],[4,1])
-
-hassubsequence([4,1,3],[4,3])
-
-hassubsequence([4,1,3,1],[1,1])
+hassubsequence([4,1,3],[4,1,3])
+hassubsequence([4,1,3],[4,1])
+hassubsequence([4,1,3],[4,3])
+hassubsequence([4,1,3,1],[1,1])
Example 80: hassubsequence
expressions that return false
-hassubsequence([4,1,3],[1,3,4])
-
-hassubsequence([4,1,3],[3,1])
-
-hassubsequence([1,2],[1,1,2])
+hassubsequence([4,1,3],[1,3,4])
+hassubsequence([4,1,3],[3,1])
+hassubsequence([1,2],[1,1,2])
5.1.1.7 String Functions
5.1.1.7.1 matchespattern
@@ -1387,8 +1362,8 @@ 5.1.1.10.2 isof
The isofExpr
syntax rule defines how the isof
function is invoked.
Example 95: orders that are also BigOrders
-http://host/service/Orders?$filter=isof(NorthwindModel.BigOrder)
-http://host/service/Orders?$filter=isof($it,NorthwindModel.BigOrder)
+http://host/service/Orders?$filter=isof(NorthwindModel.BigOrder)
+http://host/service/Orders?$filter=isof($it,NorthwindModel.BigOrder)
Example 96: orders of a customer that is a VIPCustomer
@@ -1413,7 +1388,7 @@ 5.1.1.11.3 5.1.1.12 Conditional Functions
5.1.1.12.1 case
The case
function has the following signature:
-expression case(Edm.Boolean:expression, ..., Edm.Boolean:expression)
+expression case(Edm.Boolean:expression, …, Edm.Boolean:expression)
Each parameter is a pair of expressions separated by a colon (:
), where the first expression — the condition — MUST be a Boolean expression, and the second expression — the result — may evaluate to any type.
The case function evaluates the condition in each pair, starting with the leftmost pair, and stops as soon as a condition evaluates to true
. It then returns the value of the result of this pair. It returns null
if none of the conditions in any pair evaluates to true
. Clients can specify a last pair whose condition is true
to get a non-null “default/else/otherwise” result.
Boolean expressions containing DateTimeOffset
or TimeOfDay
literals without the optional seconds part will introduce ambiguity for parsers. Clients SHOULD use whitespace or parentheses to avoid ambiguity.
@@ -1456,43 +1431,25 @@ $filter
expressions. They are represented according to the primitiveLiteral
rule in OData-ABNF.
Example 102: expressions using primitive literals
-NullValue eq null
-
-TrueValue eq true
-
-FalseValue eq false
-
-Custom.Base64UrlDecode(binary'T0RhdGE') eq 'OData'
-
-IntegerValue lt -128
-
-DoubleValue ge 0.31415926535897931e1
-
-SingleValue eq INF
-
-DecimalValue eq 34.95
-
-StringValue eq 'Say Hello,then go'
-
-DateValue eq 2012-12-03
-
-DateTimeOffsetValue eq 2012-12-03T07:16:23Z
-
-DurationValue eq duration'P12DT23H59M59.999999999999S'
-
-DurationValue eq 'P12DT23H59M59.999999999999S'
-
-TimeOfDayValue eq 07:59:59.999
-
-GuidValue eq 01234567-89ab-cdef-0123-456789abcdef
-
-Int64Value eq 0
-
-ColorEnumValue eq Sales.Pattern'Yellow'
-
-ColorEnumValue eq 'Yellow'
-
-geo.distance(Location,geography'SRID=0;Point(142.1 64.1)')
+NullValue eq null
+TrueValue eq true
+FalseValue eq false
+Custom.Base64UrlDecode(binary'T0RhdGE') eq 'OData'
+IntegerValue lt -128
+DoubleValue ge 0.31415926535897931e1
+SingleValue eq INF
+DecimalValue eq 34.95
+StringValue eq 'Say Hello,then go'
+DateValue eq 2012-12-03
+DateTimeOffsetValue eq 2012-12-03T07:16:23Z
+DurationValue eq duration'P12DT23H59M59.999999999999S'
+DurationValue eq 'P12DT23H59M59.999999999999S'
+TimeOfDayValue eq 07:59:59.999
+GuidValue eq 01234567-89ab-cdef-0123-456789abcdef
+Int64Value eq 0
+ColorEnumValue eq Sales.Pattern'Yellow'
+ColorEnumValue eq 'Yellow'
+geo.distance(Location,geography'SRID=0;Point(142.1 64.1)')
Duration literals in OData 4.0 required prefixing with “duration
”. Enumeration literals in OData 4.0 required prefixing with the qualified type name of the enumeration.
In OData 4.01, services MUST support duration and enumeration literals with or without the type prefix. OData clients that want to operate across OData 4.0 and OData 4.01 services should always include the prefix for duration and enumeration types.
diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md
index 0fcacf618..a54cc2983 100644
--- a/docs/odata-url-conventions/odata-url-conventions.md
+++ b/docs/odata-url-conventions/odata-url-conventions.md
@@ -399,11 +399,17 @@ literals are represented as two consecutive single quotes.
Example 3: valid OData URLs:
```
http://host/service/People('O''Neil')
+```
+```
http://host/service/People(%27O%27%27Neil%27)
+```
+```
http://host/service/People%28%27O%27%27Neil%27%29
+```
+```
http://host/service/Categories('Smartphone%2FTablet')
```
:::
@@ -412,9 +418,13 @@ http://host/service/Categories('Smartphone%2FTablet')
Example 4: invalid OData URLs:
```
http://host/service/People('O'Neil')
+```
+```
http://host/service/People('O%27Neil')
+```
+```
http://host/service/Categories('Smartphone/Tablet')
```
:::
@@ -794,9 +804,13 @@ specified key property name, and the canonical short form without key
property name
```
http://host/service/Employees(SSN='123-45-6789')
+```
+```
http://host/service/Employees(ID='A1245')
+```
+```
http://host/service/Employees('A1245')
```
:::
@@ -814,15 +828,25 @@ percent encoded.
Example 25: valid OData URLs:
```
http://host/service/Employees/A1245
+```
+```
http://host/service/People/O'Neil
+```
+```
http://host/service/People/O%27Neil
+```
+```
http://host/service/Categories/Smartphone%2FTablet
+```
+```
http://host/service/ThingyWithDurationKey/P12DT23H59M59.999999999999S
+```
+```
http://host/service/ThingyWithEnumerationKey/Yellow
```
:::
@@ -836,7 +860,9 @@ Example 26: multi-part key predicate, parentheses-style and
key-as-segment
```
https://host/service/OrderItems(OrderID=1,ItemNo=2)
+```
+```
https://host/service/OrderItems/1/2
```
:::
@@ -919,9 +945,13 @@ Example 29: three ways of unrelating `Categories(1)` and
`Products(0)`; the second option is supported only in OData 4.01
```
DELETE http://host/service/Categories(1)/Products/$ref?$id=../../Products(0)
+```
+```
DELETE http://host/service/Categories(1)/Products(0)/$ref
+```
+```
DELETE http://host/service/Products(0)/Category/$ref
```
:::
@@ -1149,7 +1179,9 @@ Example 37: entity restricted to a `VipCustomer` instance, resulting in
`404 Not Found` if the customer with key `1` is not a `VipCustomer`
```
http://host/service/Customers/Model.VipCustomer(1)
+```
+```
http://host/service/Customers(1)/Model.VipCustomer
```
:::
@@ -1315,25 +1347,25 @@ Example 46: if `Sales` had a structural property `ProductID` instead of
a navigation property `Product`, a "cross join" between `Sales` and
`Products` could be addressed
```
-http://host/service/$crossjoin(Products,Sales)?$filter=Products/ID eq Sales/ProductID
+http://host/service/$crossjoin(Products,Sales)?$filter=Products/ID eq Sales/ProductID
```
and would result in
```json
{
- "@odata.context":"http://host/service/$metadata#Collection(Edm.ComplexType)",
- "value":[
+ "@odata.context": "http://host/service/$metadata#Collection(Edm.ComplexType)",
+ "value": [
{
- "Products@odata.navigationLink":"Products(0)",
- "Sales@odata.navigationLink":"Sales(42)",
+ "Products@odata.navigationLink": "Products(0)",
+ "Sales@odata.navigationLink": "Sales(42)",
},
{
- "Products@odata.navigationLink":"Products(0)",
- "Sales@odata.navigationLink":"Sales(57)",
+ "Products@odata.navigationLink": "Products(0)",
+ "Sales@odata.navigationLink": "Sales(57)",
},
- ...
+ …
{
- "Products@odata.navigationLink":"Products(99)",
- "Sales@odata.navigationLink":"Sales(21)",
+ "Products@odata.navigationLink": "Products(99)",
+ "Sales@odata.navigationLink": "Sales(21)",
}
]
}
@@ -2199,13 +2231,21 @@ how the `hassubset` function is invoked.
Example 77: `hassubset` expressions that return true
```
hassubset([4,1,3],[4,1,3])
+```
+```
hassubset([4,1,3],[1,3,4])
+```
+```
hassubset([4,1,3],[3,1])
+```
+```
hassubset([4,1,3],[4,3])
+```
+```
hassubset([4,1,3,1],[1,1])
```
:::
@@ -2235,11 +2275,17 @@ items. The `hasSubsequenceMethodCallExpr` syntax rule defines how the
Example 79: `hassubsequence` expressions that return true
```
hassubsequence([4,1,3],[4,1,3])
+```
+```
hassubsequence([4,1,3],[4,1])
+```
+```
hassubsequence([4,1,3],[4,3])
+```
+```
hassubsequence([4,1,3,1],[1,1])
```
:::
@@ -2248,9 +2294,13 @@ hassubsequence([4,1,3,1],[1,1])
Example 80: `hassubsequence` expressions that return false
```
hassubsequence([4,1,3],[1,3,4])
+```
+```
hassubsequence([4,1,3],[3,1])
+```
+```
hassubsequence([1,2],[1,1,2])
```
:::
@@ -2747,6 +2797,9 @@ The `isofExpr` syntax rule defines how the `isof` function is invoked.
Example 95: orders that are also `BigOrders`
```
http://host/service/Orders?$filter=isof(NorthwindModel.BigOrder)
+```
+
+```
http://host/service/Orders?$filter=isof($it,NorthwindModel.BigOrder)
```
:::
@@ -2805,7 +2858,7 @@ parameter in the coordinate reference system signified by its SRID.
The `case` function has the following signature:
```
-expression case(Edm.Boolean:expression, ..., Edm.Boolean:expression)
+expression case(Edm.Boolean:expression, …, Edm.Boolean:expression)
```
Each parameter is a pair of expressions separated by a colon (`:`),
@@ -2933,41 +2986,77 @@ according to the `primitiveLiteral` rule in [OData-ABNF](#ODataABNF).
Example 102: expressions using primitive literals
```
NullValue eq null
+```
+```
TrueValue eq true
+```
+```
FalseValue eq false
+```
+```
Custom.Base64UrlDecode(binary'T0RhdGE') eq 'OData'
+```
+```
IntegerValue lt -128
+```
+```
DoubleValue ge 0.31415926535897931e1
+```
+```
SingleValue eq INF
+```
+```
DecimalValue eq 34.95
+```
+```
StringValue eq 'Say Hello,then go'
+```
+```
DateValue eq 2012-12-03
+```
+```
DateTimeOffsetValue eq 2012-12-03T07:16:23Z
+```
+```
DurationValue eq duration'P12DT23H59M59.999999999999S'
+```
+```
DurationValue eq 'P12DT23H59M59.999999999999S'
+```
+```
TimeOfDayValue eq 07:59:59.999
+```
+```
GuidValue eq 01234567-89ab-cdef-0123-456789abcdef
+```
+```
Int64Value eq 0
+```
+```
ColorEnumValue eq Sales.Pattern'Yellow'
+```
+```
ColorEnumValue eq 'Yellow'
+```
+```
geo.distance(Location,geography'SRID=0;Point(142.1 64.1)')
```
:::
diff --git a/odata-csdl/13 Entity Container.md b/odata-csdl/13 Entity Container.md
index 7a826a547..255b0f3bc 100644
--- a/odata-csdl/13 Entity Container.md
+++ b/odata-csdl/13 Entity Container.md
@@ -230,7 +230,7 @@ entity container located in `SomeOtherSchema`
"Extending": {
"$Kind": "EntityContainer",
"$Extends": "Some.Other.Schema.Base",
- ...
+ …
}
```
:::
@@ -248,7 +248,7 @@ elements that it defines itself, plus all child elements of the `Base`
entity container located in `SomeOtherSchema`
```xml
- ...
+ …
```
:::
diff --git a/odata-csdl/14 Vocabulary and Annotation.md b/odata-csdl/14 Vocabulary and Annotation.md
index af862b3e4..e324b9c6b 100644
--- a/odata-csdl/14 Vocabulary and Annotation.md
+++ b/odata-csdl/14 Vocabulary and Annotation.md
@@ -109,7 +109,7 @@ type specified by the term `SearchResult`
- ...
+ …
@@ -349,8 +349,7 @@ are defined in [OData-VocCore](#ODataVocCore))
"Property",
"Term"
],
- "@Core.Description": "Properties and terms annotated with this term
-MUST contain a valid URL",
+ "@Core.Description": "Properties and terms annotated with this term MUST contain a valid URL",
"@Core.RequiresType": "Edm.String"
}
```
@@ -1266,7 +1265,7 @@ the null value.
::: example
Example ##ex: type-cast segment
```
-.../self.Manager/...
+…/self.Manager/…
```
:::
@@ -1291,7 +1290,7 @@ properties:
::: example
Example ##ex: term-cast segments
```
-.../@Capabilities.SortRestrictions/...
+…/@Capabilities.SortRestrictions/…
```
:::
@@ -1311,7 +1310,7 @@ expression is the model element reached via this path.
::: example
Example ##ex: property segments in model path
```
-.../Orders/Items/Product/...
+…/Orders/Items/Product/…
```
:::
@@ -1331,11 +1330,11 @@ number of items in the collection identified by the preceding segment.
::: example
Example ##ex: property segments in instance path
```
-.../Addresses/Street
+…/Addresses/Street
```
```
-.../Addresses/$count
+…/Addresses/$count
```
:::
@@ -1355,11 +1354,11 @@ segment](#TermCast).
Example ##ex: model path segment addressing an annotation on a navigation property
vs. term cast addressing an annotation on the resource addressed by the navigation property
```
-.../Items@Core.Description
+…/Items@Core.Description
```
```
-.../Items/@Core.Description
+…/Items/@Core.Description
```
:::
@@ -1488,7 +1487,7 @@ enclosing type `self.A` of the hosting property `A2`.
"@Core.Description@Core.IsLanguageDependent": {
"$Path": "A1"
},
- "@Core.Description": "..."
+ "@Core.Description": "…"
}
},
"B": {
@@ -1506,7 +1505,7 @@ enclosing type `self.A` of the hosting property `A2`.
-
+
@@ -1533,7 +1532,7 @@ type `self.B` of the hosting property `A2`.
"@Core.Description#viaset@Core.IsLanguageDependent": {
"$Path": "B1"
},
- "@Core.Description#viaset": "..."
+ "@Core.Description#viaset": "…"
},
"self.Container/SetA/A2/@Core.Description#viaset": {
"@Core.IsLanguageDependent": {
@@ -1549,7 +1548,7 @@ type `self.B` of the hosting property `A2`.
-
+
@@ -1567,7 +1566,7 @@ type `self.A` named in the target path.
"@Core.Description#external@Core.IsLanguageDependent": {
"$Path": "A1"
},
- "@Core.Description#external": "..."
+ "@Core.Description#external": "…"
},
"self.A/A2/@Core.Description": {
"@Core.IsLanguageDependent": {
@@ -1582,7 +1581,7 @@ type `self.A` named in the target path.
:::: varxml
```xml
-
+
@@ -1716,7 +1715,6 @@ containing a path.
Example ##ex:
```json
"@UI.HyperLink": "Supplier",
-
"@Capabilities.UpdateRestrictions": {
"NonUpdatableNavigationProperties": [
"Supplier",
@@ -1775,7 +1773,6 @@ Property path expressions are represented as a string containing a path.
Example ##ex:
```json
"@UI.RefreshOnChangeOf": "ChangedAt",
-
"@Capabilities.UpdateRestrictions": {
"NonUpdatableProperties": [
"CreatedAt",
@@ -1834,7 +1831,6 @@ Example ##ex:
"@UI.DisplayName": {
"$Path": "FirstName"
},
-
"@UI.DisplayName#second": {
"$Path": "@vCard.Address#work/FullName"
}
diff --git a/odata-csdl/15 Identifier and Path Values.md b/odata-csdl/15 Identifier and Path Values.md
index 6e238a885..20db4221c 100644
--- a/odata-csdl/15 Identifier and Path Values.md
+++ b/odata-csdl/15 Identifier and Path Values.md
@@ -55,9 +55,21 @@ segments
Example ##ex: Target expressions
```
MySchema.MyEntityContainer/MyEntitySet
+```
+
+```
MySchema.MyEntityContainer/MySingleton
+```
+
+```
MySchema.MyEntityContainer/MySingleton/MyContainmentNavigationProperty
+```
+
+```
MySchema.MyEntityContainer/MySingleton/My.EntityType/MyContainmentNavProperty
+```
+
+```
MySchema.MyEntityContainer/MySingleton/MyComplexProperty/MyContainmentNavProp
```
:::
diff --git a/odata-csdl/4 CSDL Document.md b/odata-csdl/4 CSDL Document.md
index 7674fb830..cab73f4fb 100644
--- a/odata-csdl/4 CSDL Document.md
+++ b/odata-csdl/4 CSDL Document.md
@@ -35,7 +35,7 @@ Example ##ex:
{
"$Version": "4.01",
"$EntityContainer": "org.example.DemoService",
- ...
+ …
}
```
:::
@@ -72,7 +72,7 @@ Example ##ex:
- ...
+ …
```
@@ -123,19 +123,19 @@ The reference object MAY contain the members
Example ##ex: references to other CSDL documents
```json
{
- ...
+ …
"$Reference": {
"https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
- ...
+ …
},
"https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.json": {
- ...
+ …
},
"http://example.org/display/v1": {
- ...
+ …
}
},
- ...
+ …
}
```
:::
@@ -171,16 +171,16 @@ Example ##ex: references to other CSDL documents
Version="4.0">
- ...
+ …
- ...
+ …
- ...
+ …
- ...
+ …
```
:::
@@ -252,7 +252,7 @@ Example ##ex: references to entity models containing definitions of
vocabulary terms
```json
{
- ...
+ …
"$Reference": {
"https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.json": {
"$Include": [
@@ -280,7 +280,7 @@ vocabulary terms
]
}
},
- ...
+ …
}
```
:::
@@ -325,7 +325,7 @@ vocabulary terms
- ...
+ …
```
:::
@@ -392,7 +392,7 @@ The value of `$TargetNamespace` is a namespace.
Example ##ex: reference documents that contain annotations
```json
{
- ...
+ …
"$Reference": {
"http://odata.org/ann/b": {
"$IncludeAnnotations": [
@@ -415,7 +415,7 @@ Example ##ex: reference documents that contain annotations
]
}
},
- ...
+ …
}
```
:::
@@ -462,7 +462,7 @@ Example ##ex: reference documents that contain annotations
Qualifier="Tablet"
TargetNamespace="com.example.Person" />
- ...
+ …
```
:::
diff --git a/odata-csdl/5 Schema.md b/odata-csdl/5 Schema.md
index eb3b0d1bc..6436e6cb2 100644
--- a/odata-csdl/5 Schema.md
+++ b/odata-csdl/5 Schema.md
@@ -105,13 +105,13 @@ Example ##ex: document defining a schema `org.example` with an alias and a
description for the schema
```json
{
- ...
+ …
"org.example": {
"$Alias": "self",
"@Core.Description": "Example schema",
- ...
+ …
},
- ...
+ …
}
```
:::
@@ -128,7 +128,7 @@ schema
```xml
- ...
+ …
```
:::
@@ -153,7 +153,7 @@ Example ##ex: annotations targeting the `Person` type with qualifier
"$Annotations": {
"self.Person": {
"@Core.Description#Tablet": "Dummy",
- ...
+ …
}
}
}
@@ -184,7 +184,7 @@ Example ##ex: annotations should only be applied to tablet devices
```xml
- ...
+ …
```
:::
diff --git a/odata-csdl/7 Structural Property.md b/odata-csdl/7 Structural Property.md
index 0b5a24dbb..63fc92b1b 100644
--- a/odata-csdl/7 Structural Property.md
+++ b/odata-csdl/7 Structural Property.md
@@ -279,7 +279,7 @@ Example ##ex: the `Product` entity type has a navigation property to a
```json
"Product": {
"$Kind": "EntityType",
- ...
+ …
"Category": {
"$Kind": "NavigationProperty",
"$Type": "self.Category",
@@ -295,7 +295,7 @@ Example ##ex: the `Product` entity type has a navigation property to a
},
"Category": {
"$Kind": "EntityType",
- ...
+ …
"Products": {
"$Kind": "NavigationProperty",
"$Collection": true,
@@ -333,14 +333,14 @@ Example ##ex: the Product entity type has a navigation property to a
Category, which has a navigation link back to one or more products
```xml
- ...
+ …
- ...
+ …
@@ -593,7 +593,7 @@ the `Kind` property of the category.
```json
"Product": {
"$Kind": "EntityType",
- ...
+ …
"CategoryID": {},
"CategoryKind": {},
"Category": {
@@ -616,7 +616,7 @@ the `Kind` property of the category.
"Kind": {
"$Nullable": true
},
- ...
+ …
}
```
:::
@@ -657,7 +657,7 @@ category, and the `CategoryKind` property of the product is identical to
the `Kind` property of the category.
```xml
- ...
+ …
@@ -675,7 +675,7 @@ the `Kind` property of the category.
- ...
+ …
```
:::
@@ -720,7 +720,7 @@ products in that category
```json
"Category": {
"$Kind": "EntityType",
- ...
+ …
"Products": {
"$Kind": "NavigationProperty",
"$Collection": true,
@@ -751,7 +751,7 @@ Example ##ex: deletion of a category implies deletion of the related
products in that category
```xml
- ...
+ …
- ...
+ …
- ...
+ …
```
diff --git a/odata-data-aggregation-ext/1 Introduction.md b/odata-data-aggregation-ext/1 Introduction.md
index 1456fcf93..374e1b34d 100644
--- a/odata-data-aggregation-ext/1 Introduction.md
+++ b/odata-data-aggregation-ext/1 Introduction.md
@@ -686,7 +686,7 @@ Date|Month|Quarter|Year
2022-01-01|2022-01|2022-1|2022
2022-04-01|2022-04|2022-2|2022
2022-04-10|2022-04|2022-2|2022
-...|||
+…|||
:::::
::::: {style=top:150px;left:360px}
diff --git a/odata-data-aggregation-ext/3.2 Basic Aggregation.md b/odata-data-aggregation-ext/3.2 Basic Aggregation.md
index eb13d98e5..3f5756361 100644
--- a/odata-data-aggregation-ext/3.2 Basic Aggregation.md
+++ b/odata-data-aggregation-ext/3.2 Basic Aggregation.md
@@ -486,28 +486,28 @@ results in seven entities for the finest grouping level
{ "Customer": { "Country": "USA", "Name": "Joe" },
"Product": { "Category": { "Name": "Non-Food" }, "Name": "Paper" },
"Total@type": "Decimal", "Total": 1 },
- ...
+ …
```
plus additional fifteen rollup entities for subtotals: five without customer name
```json
{ "Customer": { "Country": "USA" },
"Product": { "Category": { "Name": "Food" }, "Name": "Sugar" },
"Total@type": "Decimal", "Total": 2 },
- ...
+ …
```
six without product name
```json
{ "Customer": { "Country": "USA", "Name": "Joe" },
"Product": { "Category": { "Name": "Food" } },
"Total@type": "Decimal", "Total": 6 },
- ...
+ …
```
and four with neither customer nor product name
```json
{ "Customer": { "Country": "USA" },
"Product": { "Category": { "Name": "Food" } },
"Total@type": "Decimal", "Total": 14 },
- ...
+ …
]
}
```
diff --git a/odata-data-aggregation-ext/4 Cross-Joins and Aggregation.md b/odata-data-aggregation-ext/4 Cross-Joins and Aggregation.md
index 3d896938c..f49feb631 100644
--- a/odata-data-aggregation-ext/4 Cross-Joins and Aggregation.md
+++ b/odata-data-aggregation-ext/4 Cross-Joins and Aggregation.md
@@ -23,7 +23,7 @@ results in
"value": [
{ "Products": { "Name": "Paper" }, "Sales": { "Amount": 1 } },
{ "Products": { "Name": "Sugar" }, "Sales": { "Amount": 2 } },
- ...
+ …
]
}
```
diff --git a/odata-data-aggregation-ext/5 Vocabulary for Data Aggregation.md b/odata-data-aggregation-ext/5 Vocabulary for Data Aggregation.md
index b2cc44db9..f9935d2dd 100644
--- a/odata-data-aggregation-ext/5 Vocabulary for Data Aggregation.md
+++ b/odata-data-aggregation-ext/5 Vocabulary for Data Aggregation.md
@@ -26,7 +26,7 @@ Example ##ex: an entity container with default support for everything defined in
```xml
- ...
+ …
```
:::
@@ -36,7 +36,7 @@ Example ##ex_containerrooted: Define aggregation support only for the products o
```xml
- ...
+ …
```
@@ -286,9 +286,9 @@ results in
{ "ID": "Sales Netherlands", "Name": "Sales Netherlands" },
{ "ID": "Sales Germany", "Name": "Sales Germany" },
{ "ID": "EMEA South", "Name": "EMEA South" },
- ...
+ …
{ "ID": "EMEA North", "Name": "EMEA North" },
- ...
+ …
]
}
```
@@ -312,7 +312,7 @@ results in
{ "ID": "EMEA Central", "Name": "EMEA Central" },
{ "ID": "EMEA South", "Name": "EMEA South" },
{ "ID": "EMEA North", "Name": "EMEA North" },
- ...
+ …
]
}
```
@@ -333,7 +333,7 @@ results in
"value": [
{ "ID": "Sales Office London", "Name": "Sales Office London" },
{ "ID": "Sales Office New York", "Name": "Sales Office New York" },
- ...
+ …
]
}
```
@@ -357,7 +357,7 @@ results in
"Superordinate": { "ID": "EMEA United Kingdom" } },
{ "ID": "Sales Office New York", "Name": "Sales Office New York",
"Superordinate": { "ID": "US East" } },
- ...
+ …
]
}
```
diff --git a/odata-data-aggregation-ext/6 Hierarchical Transformations.md b/odata-data-aggregation-ext/6 Hierarchical Transformations.md
index 5d58ff548..f41af2012 100644
--- a/odata-data-aggregation-ext/6 Hierarchical Transformations.md
+++ b/odata-data-aggregation-ext/6 Hierarchical Transformations.md
@@ -300,21 +300,21 @@ results in
{
"@context": "$metadata#SalesOrganizations",
"value": [
- ...
+ …
{ "ID": "Atlantis", "Name": "Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy":
[ "US", "Sales" ] },
{ "ID": "AtlantisChild", "Name": "Child of Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy":
[ "Atlantis", "US", "Sales" ] },
- ...
+ …
{ "ID": "Atlantis", "Name": "Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy":
[ "EMEA", "Sales" ] },
{ "ID": "AtlantisChild", "Name": "Child of Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy":
[ "Atlantis", "EMEA", "Sales" ] },
- ...
+ …
]
}
```
@@ -543,7 +543,7 @@ results in
"TotalAmount": null },
{ "SalesOrganization": { "ID": "US", "Name": "US" },
"TotalAmount": null },
- ...
+ …
]
}
```
diff --git a/odata-data-aggregation-ext/7 Examples.md b/odata-data-aggregation-ext/7 Examples.md
index d38ebc459..2441fff9d 100644
--- a/odata-data-aggregation-ext/7 Examples.md
+++ b/odata-data-aggregation-ext/7 Examples.md
@@ -511,7 +511,7 @@ results in
{ "@context": "#SalesOrganizations/$entity",
"ID": "US", "SalesRegion": "Corporate Sales" } },
]
- }, ...
+ }, …
]
}
```
@@ -835,16 +835,16 @@ results in
{
"@context": "$metadata#Sales(Customer(Country),Total)",
"value": [
- { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Coffee" },
+ { "Customer": { "Country": "USA" }, "Product": { "Name": "Coffee" },
"Total@type": "Decimal", "Total": 12
},
- { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Paper" },
+ { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Paper" },
"Total@type": "Decimal", "Total": 3
},
- { "Customer":{ "Country": "USA" },
+ { "Customer": { "Country": "USA" },
"Total@type": "Decimal", "Total": 19
},
- { "Customer":{ "Country": "Netherlands" },
+ { "Customer": { "Country": "Netherlands" },
"Total@type": "Decimal", "Total": 5
}
]
@@ -863,19 +863,19 @@ results in
{
"@context": "$metadata#Sales(Customer(Country),Product(Name),Total)",
"value": [
- { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Paper" },
+ { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Paper" },
"Total@type": "Decimal", "Total": 3
},
- { "Customer":{ "Country": "Netherlands" }, "Product":{ "Name": "Sugar" },
+ { "Customer": { "Country": "Netherlands" }, "Product": { "Name": "Sugar" },
"Total@type": "Decimal", "Total": 2
},
- { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Sugar" },
+ { "Customer": { "Country": "USA" }, "Product": { "Name": "Sugar" },
"Total@type": "Decimal", "Total": 2
},
- { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Coffee" },
+ { "Customer": { "Country": "USA" }, "Product": { "Name": "Coffee" },
"Total@type": "Decimal", "Total": 12
},
- { "Customer":{ "Country": "USA" }, "Product":{ "Name": "Paper" },
+ { "Customer": { "Country": "USA" }, "Product": { "Name": "Paper" },
"Total@type": "Decimal", "Total": 5
}
]
@@ -1511,14 +1511,14 @@ Note that `rolluprecursive` must preserve the preorder established by `traverse`
{ "SalesOrganization": { "ID": "Atlantis", "Name": "Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy": [ "US", "Sales" ] },
"MultiParentWeightedTotal": 6 },
- ...
+ …
{ "SalesOrganization": { "ID": "EMEA", "Name": "EMEA",
"@Aggregation.UpPath#MultiParentHierarchy": [ "Sales" ] },
"MultiParentWeightedTotal": 9 },
{ "SalesOrganization": { "ID": "Atlantis", "Name": "Atlantis",
"@Aggregation.UpPath#MultiParentHierarchy": [ "EMEA", "Sales" ] },
"MultiParentWeightedTotal": 4 },
- ...
+ …
]
}
```
@@ -1598,7 +1598,7 @@ results in
"TotalPopulation@type": "Int32", "TotalPopulation": 1412000000 },
{ "Continent": { "Name": "Asia" }, "Country": { "Name": "India" },
"TotalPopulation@type": "Int32", "TotalPopulation": 1408000000 },
- ...
+ …
]
}
```
diff --git a/odata-json-format/10 Media Entity.md b/odata-json-format/10 Media Entity.md
index ac05f3e0e..ebdd4f23c 100644
--- a/odata-json-format/10 Media Entity.md
+++ b/odata-json-format/10 Media Entity.md
@@ -18,9 +18,9 @@ Example ##ex:
"@context": "http://host/service/$metadata#Employees/$entity",
"@mediaReadLink": "Employees(1)/$value",
"@mediaContentType": "image/jpeg",
- "$value": "...base64url encoded value...",
+ "$value": "…base64url encoded value…",
"ID": 1,
- ...
+ …
}
```
:::
@@ -98,7 +98,7 @@ Example ##ex: complex value
Example ##ex: empty collection of complex values
```json
{
- "@context":"http://host/service/$metadata#Collection(Model.Address)",
+ "@context": "http://host/service/$metadata#Collection(Model.Address)",
"value": []
}
```
@@ -178,14 +178,14 @@ partial result.
Example 28:
```json
{
- "@context": "...",
+ "@context": "…",
"@count": 37,
"value": [
- { ... },
- { ... },
- { ... }
+ { … },
+ { … },
+ { … }
],
- "@nextLink": "...?$skiptoken=342r89"
+ "@nextLink": "…?$skiptoken=342r89"
}
```
:::
diff --git a/odata-json-format/15 Delta Payload.md b/odata-json-format/15 Delta Payload.md
index db7df27af..06956bb12 100644
--- a/odata-json-format/15 Delta Payload.md
+++ b/odata-json-format/15 Delta Payload.md
@@ -80,7 +80,7 @@ occurrence
{
"@context": "#Orders/$entity",
"@id": "Orders(10643)",
- "ShippingAddress":{
+ "ShippingAddress": {
"Street": "23 Tsawassen Blvd.",
"City": "Tsawassen",
"Region": "BC",
@@ -277,9 +277,9 @@ Example ##ex: deleted entity in OData 4.0 response --- note that `id` is
a property, not control information
```json
{
- "@context":"#Customers/$deletedEntity",
- "reason":"deleted",
- "id":"Customers('ANTON')"
+ "@context": "#Customers/$deletedEntity",
+ "reason": "deleted",
+ "id": "Customers('ANTON')"
}
```
:::
@@ -334,12 +334,12 @@ Example ##ex: deleted entity in OData 4.01 response with `id`
control information (prefixed with an `@`)
```json
{
- "@context":"#Customers/$deletedEntity",
- "@removed":{
- "reason":"deleted",
- "@myannoation.deletedBy":"Mario"
+ "@context": "#Customers/$deletedEntity",
+ "@removed": {
+ "reason": "deleted",
+ "@myannoation.deletedBy": "Mario"
},
- "@id":"Customers('ANTON')"
+ "@id": "Customers('ANTON')"
}
```
:::
@@ -350,8 +350,8 @@ control information and instead all key fields (`ID` is the
single key field of `Customer`)
```json
{
- "@removed":{},
- "ID":"ANTON"
+ "@removed": {},
+ "ID": "ANTON"
}
```
:::
@@ -457,7 +457,7 @@ Prefer: return=minimal, continue-on-error
{
"@Org.OData.Core.V1.ContentID": "3",
"@removed": {},
- "CustomerID":"ANTON"
+ "CustomerID": "ANTON"
},
{
"@Org.OData.Core.V1.ContentID": "4",
@@ -494,7 +494,7 @@ Prefer: return=minimal, continue-on-error
"@context": "#Customers/$link",
"@Org.OData.Core.V1.ContentID": "5",
"source": "Customers('ANATR')",
- "relationship":" Orders",
+ "relationship": "Orders",
"target": "Orders(10643)"
},
{
@@ -567,7 +567,7 @@ Preference-Applied: return=minimal, continue-on-error
},
{
"@Org.OData.Core.V1.ContentID": "3",
- "CustomerID":"ANTON"
+ "CustomerID": "ANTON",
"@Org.OData.Core.V1.DataModificationException": {
"failedOperation": "delete",
"responseCode": 400,
@@ -601,7 +601,7 @@ Preference-Applied: return=minimal, continue-on-error
"@context": "#Customers/$deletedLink",
"@Org.OData.Core.V1.ContentID": "5",
"source": "Customers('ANATR')",
- "relationship":" Orders",
+ "relationship": "Orders",
"target": "Orders(10643)",
"@Org.OData.Core.V1.DataModificationException": {
"failedOperation": "link",
diff --git a/odata-json-format/16 Bound Function.md b/odata-json-format/16 Bound Function.md
index 5f0f029d2..73e0a2ed7 100644
--- a/odata-json-format/16 Bound Function.md
+++ b/odata-json-format/16 Bound Function.md
@@ -67,7 +67,7 @@ applicable
{
"@context": "http://host/service/$metadata#Employees/$entity",
"#Model.RemainingVacation": {},
- ...
+ …
}
```
:::
@@ -82,7 +82,7 @@ alias for the `Year` parameter
"title": "Remaining vacation from year.",
"target": "Employees(2)/RemainingVacation(Year=@Year)"
},
- ...
+ …
}
```
:::
@@ -96,7 +96,7 @@ Example ##ex: full representation in a collection
"title": "Remaining Vacation",
"target": "Managers(22)/Employees/RemainingVacation"
},
- "value": [ ... ]
+ "value": [ … ]
}
```
:::
@@ -108,7 +108,7 @@ Example ##ex: full representation in a nested collection
"@context": "http://host/service/$metadata#Employees/$entity",
"@type": "Model.Manager",
"ID":22,
- ...
+ …
"Employees#RemainingVacation": {
"title": "RemainingVacation",
"target": "Managers(22)/Employees/RemainingVacation"
@@ -170,7 +170,7 @@ Example ##ex: minimal representation in an entity
{
"@context": "http://host/service/$metadata#LeaveRequests/$entity",
"#Model.Approve": {},
- ...
+ …
}
```
:::
@@ -184,7 +184,7 @@ Example ##ex: full representation in an entity:
"title": "Approve Leave Request",
"target": "LeaveRequests(2)/Approve"
},
- ...
+ …
}
```
:::
@@ -198,7 +198,7 @@ Example ##ex: full representation in a collection
"title": "Approve All Leave Requests",
"target": "Employees(22)/Model.Manager/LeaveRequests/Approve"
},
- "value": [ ... ]
+ "value": [ … ]
}
```
:::
@@ -210,7 +210,7 @@ Example ##ex: full representation in a nested collection
"@context": "http://host/service/$metadata#Employees/$entity",
"@type": "Model.Manager",
"ID": 22,
- ...
+ …
"LeaveRequests#Model.Approve": {
"title": "Approve All Leave Requests",
"target": "Employees(22)/Model.Manager/LeaveRequests/Approve"
diff --git a/odata-json-format/19 Batch Requests and Responses.md b/odata-json-format/19 Batch Requests and Responses.md
index fffa230cd..fadc49519 100644
--- a/odata-json-format/19 Batch Requests and Responses.md
+++ b/odata-json-format/19 Batch Requests and Responses.md
@@ -447,7 +447,7 @@ Content-Type: application/json
"body":
}
],
- "@nextLink": "...?$skiptoken=YmF0Y2gx"
+ "@nextLink": "…?$skiptoken=YmF0Y2gx"
}
```
diff --git a/odata-json-format/20 Instance Annotations.md b/odata-json-format/20 Instance Annotations.md
index 0601e8a6f..26a9fb628 100644
--- a/odata-json-format/20 Instance Annotations.md
+++ b/odata-json-format/20 Instance Annotations.md
@@ -160,8 +160,8 @@ Example ##ex:
}
],
"innererror": {
- "trace": [...],
- "context": {...}
+ "trace": […],
+ "context": {…}
}
}
}
diff --git a/odata-json-format/4 Common Characteristics.md b/odata-json-format/4 Common Characteristics.md
index 5b1a5c307..ce6360b4a 100644
--- a/odata-json-format/4 Common Characteristics.md
+++ b/odata-json-format/4 Common Characteristics.md
@@ -101,11 +101,11 @@ Example ##ex:
```json
{
"@context": "http://host/service/$metadata#Customers/$entity",
- ...
+ …
"@editLink": "Customers('ALFKI')",
- ...
+ …
"Orders@navigationLink": "Customers('ALFKI')/Orders",
- ...
+ …
}
```
:::
@@ -230,7 +230,7 @@ Example ##ex:
{
"@context": "http://host/service/$metadata#Customers/$entity",
"@metadataEtag": "W/\"A1FF3E230954908F\"",
- ...
+ …
}
```
:::
@@ -338,7 +338,7 @@ metadata document of the same service with a dynamic property of type
"ID": 2,
"DynamicValue@type": "Date",
"DynamicValue": "2016-09-22",
- ...
+ …
}
```
:::
@@ -351,7 +351,7 @@ metadata document of a different service
"@context": "http://host/service/$metadata#Customers/$entity",
"@type": "http://host/alternate/$metadata#Model.VipCustomer",
"ID": 2,
- ...
+ …
}
```
:::
@@ -589,7 +589,7 @@ Example ##ex:
"@mediaReadLink": "Employees(1)/$value",
"@mediaContentType": "image/jpeg",
"ID": 1,
- ...
+ …
}
```
:::
@@ -632,7 +632,7 @@ Example ##ex: Annotating primitive values within a collection
"JulieSwa@live.com",
"Julie.Swansworth@work.com"
],
- ...
+ …
}
```
:::
diff --git a/odata-json-format/7 Structural Property.md b/odata-json-format/7 Structural Property.md
index d7b56f083..4e88b435b 100644
--- a/odata-json-format/7 Structural Property.md
+++ b/odata-json-format/7 Structural Property.md
@@ -100,7 +100,7 @@ Example ##ex:
```json
{
"@context": "http://host/service/$metadata#Customers/$entity",
- ...
+ …
"Address": {
"Street": "Obere Str. 57",
"City": "Berlin",
@@ -128,12 +128,12 @@ Example ##ex: partial collection of strings with next link
```json
{
"@context": "http://host/service/$metadata#Customers/$entity",
- ...
+ …
"EmailAddresses": [
"Julie@Swansworth.com",
"Julie.Swansworth@work.com"
],
- "EmailAddresses@nextLink": "..."
+ "EmailAddresses@nextLink": "…"
}
```
:::
@@ -164,7 +164,7 @@ Example ##ex: partial collection of complex values with next link
"Carrier": "Sprint"
}
],
- "PhoneNumbers@nextLink": "..."
+ "PhoneNumbers@nextLink": "…"
}
```
:::
@@ -221,9 +221,9 @@ Example ##ex:
```json
{
"@context": "http://host/service/$metadata#Customers/$entity",
- ...
+ …
"Orders@navigationLink": "Customers('ALFKI')/Orders",
- ...
+ …
}
```
:::
@@ -248,9 +248,9 @@ Example ##ex:
```json
{
"@context": "http://host/service/$metadata#Customers/$entity",
- ...
+ …
"Orders@associationLink": "Customers('ALFKI')/Orders/$ref",
- ...
+ …
}
```
:::
@@ -283,9 +283,9 @@ Example ##ex:
{
"@context": "http://host/service/$metadata#Customers/$entity",
"Orders@count": 42,
- "Orders": [ ... ],
- "Orders@nextLink": "...",
- ...
+ "Orders": [ … ],
+ "Orders@nextLink": "…",
+ …
}
```
:::
@@ -306,21 +306,21 @@ related to existing products:
{
"ID": 11643,
"Amount": 100,
- ...,
+ …,
"Customer": {
"ID": "ANEWONE",
- ...
+ …
},
"Items": [
{
"Product": { "@id": "Products(28)" },
"Quantity": 1,
- ...
+ …
},
{
"Product": { "@id": "Products(39)" },
"Quantity": 5,
- ...
+ …
}
]
}
@@ -440,7 +440,7 @@ Example ##ex: ETag for a collection of related entities
"@etag": "W/\"MjAxMy0wNS0yN1QxMTo1OFo=\"",
"ID": 1234,
"Items@etag": "W/\"MjAxOS0wMy0xMlQxMDoyMlo=\""
- ...
+ …
}
```
:::
@@ -489,13 +489,13 @@ Example ##ex:
```json
{
"@context": "http://host/service/$metadata#Products/$entity",
- ...
+ …
"Thumbnail@mediaReadLink": "http://server/Thumbnail546.jpg",
"Thumbnail@mediaEditLink": "http://server/uploads/Thumbnail546.jpg",
"Thumbnail@mediaContentType": "image/jpeg",
"Thumbnail@mediaEtag": "W/\"####\"",
- "Thumbnail": "...base64url encoded value...",
- ...
+ "Thumbnail": "…base64url encoded value…",
+ …
}
```
:::
diff --git a/odata-protocol/10 Context URL.md b/odata-protocol/10 Context URL.md
index 7f0a35851..d24e0f61a 100644
--- a/odata-protocol/10 Context URL.md
+++ b/odata-protocol/10 Context URL.md
@@ -577,6 +577,6 @@ Context URL template:
{context-url}#Collection(Edm.ComplexType)
-Responses to requests to the virtual collections `$crossjoin(...)` (see
+Responses to requests to the virtual collections `$crossjoin(…)` (see
[OData-URL](#ODataURL)) use the built-in abstract complex type. Single
instances in these responses do not have a context URL.
diff --git a/odata-protocol/11.4 Data Modification.md b/odata-protocol/11.4 Data Modification.md
index bf5f0a861..fc3da90b5 100644
--- a/odata-protocol/11.4 Data Modification.md
+++ b/odata-protocol/11.4 Data Modification.md
@@ -212,7 +212,7 @@ entity with links to an existing manager (of managers) and to two existing emplo
annotation to the `Manager` and `DirectReports` navigation properties
```json
{
- "@odata.type":"#Northwind.Manager",
+ "@odata.type": "#Northwind.Manager",
"ID": 1,
"FirstName": "Pat",
"LastName": "Griswold",
@@ -231,7 +231,7 @@ entity with links to an existing manager (of managers) and to two existing emplo
within the `Manager` and `DirectReports` navigation properties
```json
{
- "@type":"#Northwind.Manager",
+ "@type": "#Northwind.Manager",
"ID": 1,
"FirstName": "Pat",
"LastName": "Griswold",
@@ -429,7 +429,7 @@ reports; two existing employees and one new employee named
`Suzanne Brown`. The `LastName` of employee 6 is updated to `Smith`.
```json
{
- "@type":"#Northwind.Manager",
+ "@type": "#Northwind.Manager",
"FirstName" : "Patricia",
"DirectReports": [
{
@@ -744,10 +744,10 @@ would only include control information for the stream property, not the stream d
```json
{
"@context": "http://host/service/$metadata#Products/$entity",
- ...
+ …
"Thumbnail@mediaReadLink": "http://server/Thumbnail546.jpg",
"Thumbnail@mediaEditLink": "http://server/uploads/Thumbnail546.jpg",
- ...
+ …
}
```
The stream data can then be requested using the media read link:
@@ -1086,8 +1086,7 @@ Entities](#UpdateaCollectionofEntities) applies.
::: example
Example ##ex: change the color of all beige-brown products
```json
-PATCH /service/Products/$filter(@bar)/$each?@bar=Color eq
-'beige-brown'
+PATCH /service/Products/$filter(@bar)/$each?@bar=Color eq 'beige-brown'
Content-Type: application/json
{
diff --git a/odata-protocol/11.5 Operations.md b/odata-protocol/11.5 Operations.md
index 776ee46d4..7e7ac8573 100644
--- a/odata-protocol/11.5 Operations.md
+++ b/odata-protocol/11.5 Operations.md
@@ -108,14 +108,14 @@ a Customer that includes the `SampleEntities.MostRecentOrder` function
bound to the entity
```json
{
- "@context": ...,
+ "@context": …,
"CustomerID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"#SampleEntities.MostRecentOrder": {
"title": "Most Recent Order",
"target": "Customers('ALFKI')/SampleEntities.MostRecentOrder()"
},
- ...
+ …
}
```
:::
@@ -133,11 +133,11 @@ Example ##ex: the `SampleEntities.MostRecentOrder` function is not
available for customer `ALFKI`
```json
{
- "@context": ...,
+ "@context": …,
"CustomerID": "ALFKI",
"CompanyName": "Alfreds Futterkiste",
"#SampleEntities.MostRecentOrder": null,
- ...
+ …
}
```
:::
@@ -211,7 +211,7 @@ returned by the composable `MyShoppingCart` function import
```
POST http://host/service/MyShoppingCart()/Items
-...
+…
```
:::
diff --git a/odata-protocol/11.7 Batch Requests.md b/odata-protocol/11.7 Batch Requests.md
index 0363af910..053512319 100644
--- a/odata-protocol/11.7 Batch Requests.md
+++ b/odata-protocol/11.7 Batch Requests.md
@@ -205,7 +205,7 @@ GET https://host:1234/path/service/People(1) HTTP/1.1
::: example
Example ##ex:
-```
+```json
PATCH /path/service/People(1) HTTP/1.1
Host: myserver.mydomain.org:1234
Content-Type: application/json
diff --git a/odata-url-conventions/1 Introduction.md b/odata-url-conventions/1 Introduction.md
index c8062dded..e7c646ab1 100644
--- a/odata-url-conventions/1 Introduction.md
+++ b/odata-url-conventions/1 Introduction.md
@@ -158,11 +158,17 @@ literals are represented as two consecutive single quotes.
Example ##ex: valid OData URLs:
```
http://host/service/People('O''Neil')
+```
+```
http://host/service/People(%27O%27%27Neil%27)
+```
+```
http://host/service/People%28%27O%27%27Neil%27%29
+```
+```
http://host/service/Categories('Smartphone%2FTablet')
```
:::
@@ -171,9 +177,13 @@ http://host/service/Categories('Smartphone%2FTablet')
Example ##ex: invalid OData URLs:
```
http://host/service/People('O'Neil')
+```
+```
http://host/service/People('O%27Neil')
+```
+```
http://host/service/Categories('Smartphone/Tablet')
```
:::
diff --git a/odata-url-conventions/4 Resource Path.md b/odata-url-conventions/4 Resource Path.md
index a4620cfe1..41786fcc2 100644
--- a/odata-url-conventions/4 Resource Path.md
+++ b/odata-url-conventions/4 Resource Path.md
@@ -354,9 +354,13 @@ specified key property name, and the canonical short form without key
property name
```
http://host/service/Employees(SSN='123-45-6789')
+```
+```
http://host/service/Employees(ID='A1245')
+```
+```
http://host/service/Employees('A1245')
```
:::
@@ -374,15 +378,25 @@ percent encoded.
Example ##ex: valid OData URLs:
```
http://host/service/Employees/A1245
+```
+```
http://host/service/People/O'Neil
+```
+```
http://host/service/People/O%27Neil
+```
+```
http://host/service/Categories/Smartphone%2FTablet
+```
+```
http://host/service/ThingyWithDurationKey/P12DT23H59M59.999999999999S
+```
+```
http://host/service/ThingyWithEnumerationKey/Yellow
```
:::
@@ -396,7 +410,9 @@ Example ##ex: multi-part key predicate, parentheses-style and
key-as-segment
```
https://host/service/OrderItems(OrderID=1,ItemNo=2)
+```
+```
https://host/service/OrderItems/1/2
```
:::
@@ -479,9 +495,13 @@ Example ##ex: three ways of unrelating `Categories(1)` and
`Products(0)`; the second option is supported only in OData 4.01
```
DELETE http://host/service/Categories(1)/Products/$ref?$id=../../Products(0)
+```
+```
DELETE http://host/service/Categories(1)/Products(0)/$ref
+```
+```
DELETE http://host/service/Products(0)/Category/$ref
```
:::
@@ -710,7 +730,9 @@ Example ##ex: entity restricted to a `VipCustomer` instance, resulting in
`404 Not Found` if the customer with key `1` is not a `VipCustomer`
```
http://host/service/Customers/Model.VipCustomer(1)
+```
+```
http://host/service/Customers(1)/Model.VipCustomer
```
:::
@@ -876,25 +898,25 @@ Example ##ex: if `Sales` had a structural property `ProductID` instead of
a navigation property `Product`, a "cross join" between `Sales` and
`Products` could be addressed
```
-http://host/service/$crossjoin(Products,Sales)?$filter=Products/ID eq Sales/ProductID
+http://host/service/$crossjoin(Products,Sales)?$filter=Products/ID eq Sales/ProductID
```
and would result in
```json
{
- "@odata.context":"http://host/service/$metadata#Collection(Edm.ComplexType)",
- "value":[
+ "@odata.context": "http://host/service/$metadata#Collection(Edm.ComplexType)",
+ "value": [
{
- "Products@odata.navigationLink":"Products(0)",
- "Sales@odata.navigationLink":"Sales(42)",
+ "Products@odata.navigationLink": "Products(0)",
+ "Sales@odata.navigationLink": "Sales(42)",
},
{
- "Products@odata.navigationLink":"Products(0)",
- "Sales@odata.navigationLink":"Sales(57)",
+ "Products@odata.navigationLink": "Products(0)",
+ "Sales@odata.navigationLink": "Sales(57)",
},
- ...
+ …
{
- "Products@odata.navigationLink":"Products(99)",
- "Sales@odata.navigationLink":"Sales(21)",
+ "Products@odata.navigationLink": "Products(99)",
+ "Sales@odata.navigationLink": "Sales(21)",
}
]
}
diff --git a/odata-url-conventions/5 Query Options.md b/odata-url-conventions/5 Query Options.md
index 8ee9653e0..cc1b6b331 100644
--- a/odata-url-conventions/5 Query Options.md
+++ b/odata-url-conventions/5 Query Options.md
@@ -795,13 +795,21 @@ how the `hassubset` function is invoked.
Example ##ex: `hassubset` expressions that return true
```
hassubset([4,1,3],[4,1,3])
+```
+```
hassubset([4,1,3],[1,3,4])
+```
+```
hassubset([4,1,3],[3,1])
+```
+```
hassubset([4,1,3],[4,3])
+```
+```
hassubset([4,1,3,1],[1,1])
```
:::
@@ -831,11 +839,17 @@ items. The `hasSubsequenceMethodCallExpr` syntax rule defines how the
Example ##ex: `hassubsequence` expressions that return true
```
hassubsequence([4,1,3],[4,1,3])
+```
+```
hassubsequence([4,1,3],[4,1])
+```
+```
hassubsequence([4,1,3],[4,3])
+```
+```
hassubsequence([4,1,3,1],[1,1])
```
:::
@@ -844,9 +858,13 @@ hassubsequence([4,1,3,1],[1,1])
Example ##ex: `hassubsequence` expressions that return false
```
hassubsequence([4,1,3],[1,3,4])
+```
+```
hassubsequence([4,1,3],[3,1])
+```
+```
hassubsequence([1,2],[1,1,2])
```
:::
@@ -1343,6 +1361,9 @@ The `isofExpr` syntax rule defines how the `isof` function is invoked.
Example ##ex: orders that are also `BigOrders`
```
http://host/service/Orders?$filter=isof(NorthwindModel.BigOrder)
+```
+
+```
http://host/service/Orders?$filter=isof($it,NorthwindModel.BigOrder)
```
:::
@@ -1401,7 +1422,7 @@ parameter in the coordinate reference system signified by its SRID.
The `case` function has the following signature:
```
-expression case(Edm.Boolean:expression, ..., Edm.Boolean:expression)
+expression case(Edm.Boolean:expression, …, Edm.Boolean:expression)
```
Each parameter is a pair of expressions separated by a colon (`:`),
@@ -1529,41 +1550,77 @@ according to the `primitiveLiteral` rule in [OData-ABNF](#ODataABNF).
Example ##ex: expressions using primitive literals
```
NullValue eq null
+```
+```
TrueValue eq true
+```
+```
FalseValue eq false
+```
+```
Custom.Base64UrlDecode(binary'T0RhdGE') eq 'OData'
+```
+```
IntegerValue lt -128
+```
+```
DoubleValue ge 0.31415926535897931e1
+```
+```
SingleValue eq INF
+```
+```
DecimalValue eq 34.95
+```
+```
StringValue eq 'Say Hello,then go'
+```
+```
DateValue eq 2012-12-03
+```
+```
DateTimeOffsetValue eq 2012-12-03T07:16:23Z
+```
+```
DurationValue eq duration'P12DT23H59M59.999999999999S'
+```
+```
DurationValue eq 'P12DT23H59M59.999999999999S'
+```
+```
TimeOfDayValue eq 07:59:59.999
+```
+```
GuidValue eq 01234567-89ab-cdef-0123-456789abcdef
+```
+```
Int64Value eq 0
+```
+```
ColorEnumValue eq Sales.Pattern'Yellow'
+```
+```
ColorEnumValue eq 'Yellow'
+```
+```
geo.distance(Location,geography'SRID=0;Point(142.1 64.1)')
```
:::
From 9c9fd29fb44dc01780f65448e3af545aa0493afe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Mon, 4 Dec 2023 12:31:44 +0100
Subject: [PATCH 19/22] Analyse with puppeteer (#221)
---
lib/README.md | 4 ++++
lib/selector.mjs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
package.json | 1 +
3 files changed, 58 insertions(+)
create mode 100644 lib/selector.mjs
diff --git a/lib/README.md b/lib/README.md
index 40483f2b7..ebca07a42 100644
--- a/lib/README.md
+++ b/lib/README.md
@@ -96,6 +96,10 @@ The following scripts can be executed manually or as part of a GitHub Action:
- a copy of the common [`styles`](../styles) folder
- a copy of the document-specific `*/images` folder, if this exists.
- [`npm run pdf`](build-pdf.mjs) runs the PDF conversion and writes the PDF document into the [`docs/*`](../docs) folder.
+- [`npm run select []`](selector.mjs) selects parts of the generated HTML documents by executing a CSS selector and optionally an XPath expression relative to each match. For example, syntax errors in JSON code snippets can be detected with
+ ```sh
+ npm run select ".json .er" "self::*[.!='…']/text()"
+ ```
- [`npm test`](../test) runs a test suite.
## A note on diagrams
diff --git a/lib/selector.mjs b/lib/selector.mjs
new file mode 100644
index 000000000..30233f131
--- /dev/null
+++ b/lib/selector.mjs
@@ -0,0 +1,53 @@
+import puppeteer from "puppeteer";
+import iterator from "./iterator.js";
+
+var docs = [];
+iterator(function (srcname, name, variant) {
+ docs.push(name);
+});
+var browser = await puppeteer.launch({ headless: "new" });
+var exit_code = 0;
+for (var name of docs) {
+ var heading = undefined;
+ console.group(name);
+ var page = await browser.newPage();
+ await page.goto(`${import.meta.dirname}/../docs/${name}/${name}.html`, {
+ waitUntil: "networkidle2",
+ });
+ for (var r of await Promise.all(
+ (
+ await Promise.all(
+ (await page.$$(process.argv[2])).map(async function (elem) {
+ var elems = process.argv[3]
+ ? await elem.$$("xpath/" + process.argv[3])
+ : [elem];
+ if (elems.length > 0) exit_code = 1;
+ return elems.map((elem) =>
+ elem.evaluate(function (e) {
+ return {
+ heading: document.evaluate(
+ "preceding::*[self::h1|self::h2|self::h3|self::h4|self::h5|self::h6][1]",
+ e,
+ () => {},
+ XPathResult.FIRST_ORDERED_NODE_TYPE,
+ ).singleNodeValue.textContent,
+ match:
+ e.nodeType === Node.ELEMENT_NODE ? e.outerHTML : e.nodeValue,
+ };
+ }),
+ );
+ }),
+ )
+ ).flat(),
+ )) {
+ if (r.heading !== heading) {
+ if (heading) console.groupEnd();
+ console.group(r.heading);
+ heading = r.heading;
+ }
+ console.log(r.match);
+ }
+ if (heading) console.groupEnd();
+ console.groupEnd();
+}
+process.exit(exit_code);
diff --git a/package.json b/package.json
index 3b3813213..2f71ce2cf 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
"build": "node lib/build.js",
"pdf": "node lib/build-pdf.js",
"start": "node lib/server",
+ "select": "node lib/selector.mjs",
"test": "c8 -r html -r text mocha",
"clean-xxx": "node lib/clean.mjs odata-xxx/temp odata-xxx-v4.0"
},
From 46e8153f2d3d873ae9553c5df686b6d0db6cfe16 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Mon, 4 Dec 2023 14:10:00 +0100
Subject: [PATCH 20/22] Various errata (#223)
---
docs/odata-csdl-json/odata-csdl-json.html | 2 +-
docs/odata-csdl-json/odata-csdl-json.md | 2 +-
docs/odata-csdl-xml/odata-csdl-xml.html | 2 +-
docs/odata-csdl-xml/odata-csdl-xml.md | 2 +-
docs/odata-json-format/odata-json-format.html | 2 +-
docs/odata-json-format/odata-json-format.md | 2 +-
docs/odata-protocol/odata-protocol.html | 24 +++++++++----------
docs/odata-protocol/odata-protocol.md | 24 +++++++++----------
.../odata-url-conventions.html | 4 ++--
.../odata-url-conventions.md | 4 ++--
odata-csdl/1 Introduction.md | 2 +-
odata-json-format/20 Instance Annotations.md | 2 +-
odata-protocol/11 Data Service Requests.md | 2 +-
odata-protocol/12 Conformance.md | 22 ++++++++---------
odata-url-conventions/4 Resource Path.md | 4 ++--
15 files changed, 50 insertions(+), 50 deletions(-)
diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html
index a8fcf83d1..a9c07777f 100644
--- a/docs/odata-csdl-json/odata-csdl-json.html
+++ b/docs/odata-csdl-json/odata-csdl-json.html
@@ -635,7 +635,7 @@ 3.3
Edm.Date
and Edm.DateTimeOffset
follow XML-Schema-2 and use the proleptic Gregorian calendar, allowing the year 0000
(equivalent to 1 BCE) and negative years (year -0001
being equivalent to 2 BCE etc.). The supported date range is service-specific and typically depends on the underlying persistency layer, e.g. SQL only supports years 0001
to 9999
.
Edm.Decimal
with a Scale
value of floating
, Edm.Double
, and Edm.Single
allow the special numeric values -INF
, INF
, and NaN
.
Edm.Stream
is a primitive type that can be used as a property of an entity type or complex type, the underlying type for a type definition, or the binding parameter or return type of an action or function. Edm.Stream
, or a type definition whose underlying type is Edm.Stream
, cannot be used in collections or for non-binding parameters to functions or actions.
-Some of these types allow facets, defined in section “Type Facets”.
+Some of these types allow facets, defined in section “Type Facets”.
See rule primitiveLiteral
in OData-ABNF for the representation of primitive type values in URLs and OData-JSON for the representation in requests and responses.
3.4 Type Facets
The facets in the following subsections modify or constrain the acceptable values of primitive typed model elements, for example a structural property, action or function parameter, action or function return type, or term.
diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md
index 46dfa0f37..930dbbef3 100644
--- a/docs/odata-csdl-json/odata-csdl-json.md
+++ b/docs/odata-csdl-json/odata-csdl-json.md
@@ -610,7 +610,7 @@ parameter or return type of an [action](#Action) or
underlying type is `Edm.Stream`, cannot be used in collections or for
non-binding parameters to functions or actions.
-Some of these types allow [facets](#TypeFacets), defined in section
+Some of these types allow facets, defined in section
"[Type Facets](#TypeFacets)".
See rule `primitiveLiteral` in [OData-ABNF](#ODataABNF) for the
diff --git a/docs/odata-csdl-xml/odata-csdl-xml.html b/docs/odata-csdl-xml/odata-csdl-xml.html
index 5a99b05d3..4f19532fa 100644
--- a/docs/odata-csdl-xml/odata-csdl-xml.html
+++ b/docs/odata-csdl-xml/odata-csdl-xml.html
@@ -628,7 +628,7 @@ 3.3
Edm.Date
and Edm.DateTimeOffset
follow XML-Schema-2 and use the proleptic Gregorian calendar, allowing the year 0000
(equivalent to 1 BCE) and negative years (year -0001
being equivalent to 2 BCE etc.). The supported date range is service-specific and typically depends on the underlying persistency layer, e.g. SQL only supports years 0001
to 9999
.
Edm.Decimal
with a Scale
value of floating
, Edm.Double
, and Edm.Single
allow the special numeric values -INF
, INF
, and NaN
.
Edm.Stream
is a primitive type that can be used as a property of an entity type or complex type, the underlying type for a type definition, or the binding parameter or return type of an action or function. Edm.Stream
, or a type definition whose underlying type is Edm.Stream
, cannot be used in collections or for non-binding parameters to functions or actions.
-Some of these types allow facets, defined in section “Type Facets”.
+Some of these types allow facets, defined in section “Type Facets”.
See rule primitiveLiteral
in OData-ABNF for the representation of primitive type values in URLs and OData-JSON for the representation in requests and responses.
3.4 Type Facets
The facets in the following subsections modify or constrain the acceptable values of primitive typed model elements, for example a structural property, action or function parameter, action or function return type, or term.
diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md
index dd2ecb0b0..c2b36f72e 100644
--- a/docs/odata-csdl-xml/odata-csdl-xml.md
+++ b/docs/odata-csdl-xml/odata-csdl-xml.md
@@ -550,7 +550,7 @@ parameter or return type of an [action](#Action) or
underlying type is `Edm.Stream`, cannot be used in collections or for
non-binding parameters to functions or actions.
-Some of these types allow [facets](#TypeFacets), defined in section
+Some of these types allow facets, defined in section
"[Type Facets](#TypeFacets)".
See rule `primitiveLiteral` in [OData-ABNF](#ODataABNF) for the
diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html
index c529d6b46..e829a010e 100644
--- a/docs/odata-json-format/odata-json-format.html
+++ b/docs/odata-json-format/odata-json-format.html
@@ -2016,7 +2016,7 @@ OData-VocCore. The annotation MAY include a retryLink
property that can be used by the client to attempt to re-fetch the resource.
21.3.3 Collection Errors
Collections within a success payload can contain primitive values that are in error, or structured values that are in error, if the client has specified the continue-on-error
preference. Such elements are annotated as described above. Primitive elements within a collection are annotated using the collectionAnnotations
control information.
-Services can return partial collections within a success payload, for example, if they encounter an error while retrieving the collection and the client has specified the continue-on-error
preference. In this case, the service MUST include a nextLink
. The nextLink
can be used to attempt retrieving the remaining members of the collection and could return an error indicating that the remaining members are not available.
+Services can return partial collections within a success payload, for example, if they encounter an error while retrieving the collection and the client has specified the continue-on-error
preference. In this case, the service MUST include a nextLink
. The nextLink
can be used to attempt retrieving the remaining members of the collection and could return an error indicating that the remaining members are not available.
22 Extensibility
Implementations can add instance annotations of the form @namespace.termname
or property@namespace.termname
to any JSON object, where property
MAY or MAY NOT match the name of a name/value pair within the JSON object. However, the namespace MUST NOT start with odata
and SHOULD NOT be required to be understood by the receiving party in order to correctly interpret the rest of the payload as the receiving party MUST ignore unknown annotations not defined in this version of the OData JSON Specification.
diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md
index 66f21aa86..8c23db484 100644
--- a/docs/odata-json-format/odata-json-format.md
+++ b/docs/odata-json-format/odata-json-format.md
@@ -3752,7 +3752,7 @@ the client has specified the
`continue-on-error` preference. In
this case, the service MUST include a
[`nextLink`](#ControlInformationnextLinkodatanextLink).
-The [`nextLink`](#ControlInformationnextLinkodatanextLink) can be used to attempt retrieving the remaining members of the collection and could return an error indicating that the remaining
+The `nextLink` can be used to attempt retrieving the remaining members of the collection and could return an error indicating that the remaining
members are not available.
-------
diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html
index 075ab1b92..984170c42 100644
--- a/docs/odata-protocol/odata-protocol.html
+++ b/docs/odata-protocol/odata-protocol.html
@@ -1269,7 +1269,7 @@ 11.2.2 Requesting Individual Entities
To retrieve an individual entity, the client makes a GET
request to a URL that identifies the entity, e.g. its read URL.
The read URL can be obtained from a response payload containing that instance, for example as a readLink
or editLink
in an OData-JSON payload. In addition, services MAY support conventions for constructing a read URL using the entity’s key value(s), as described in OData-URL.
-The set of structural or navigation properties to return may be specified through $select
or $expand
system query options.
+The set of structural or navigation properties to return may be specified through $select
or $expand
system query options.
Clients MUST be prepared to receive additional properties in an entity or complex type instance that are not advertised in metadata, even for types not marked as open.
Properties that are not available, for example due to permissions, are not returned. In this case, the Core.Permissions
annotation, defined in OData-VocCore MUST be returned for the property with a value of None
.
If no entity exists with the specified request URL, the service responds with 404 Not Found
.
@@ -2602,22 +2602,22 @@ 12.1.1 OData 4.0 Minimal Conformance Level
In order to conform to the OData 4.0 Minimal conformance level, a service:
-- MUST publish a service document at the service root (section 11.1.1)
+- MUST publish a service document at the service root (section 11.1.1)
- MUST return data according to the OData-JSON format
-- MUST use server-driven paging when returning partial results (section 11.2.6.7) and not use any other mechanism
-- MUST return the appropriate
OData-Version
header (section 8.1.5)
+- MUST use server-driven paging when returning partial results (section 11.2.6.7) and not use any other mechanism
+- MUST return the appropriate
OData-Version
header (section 8.1.5)
- MUST conform to the semantics the following headers, or fail the request
-Accept
(section 8.2.1)
-OData-MaxVersion
(section 8.2.7)
+Accept
(section 8.2.1)
+OData-MaxVersion
(section 8.2.7)
-- MUST follow OData guidelines for extensibility (section 6 and all subsections)
-- MUST successfully parse the request according to OData-ABNF for any supported system query options and either follow the specification or return
501 Not Implemented
for any unsupported functionality (section 9.3.1)
+- MUST follow OData guidelines for extensibility (section 6 and all subsections)
+- MUST successfully parse the request according to OData-ABNF for any supported system query options and either follow the specification or return
501 Not Implemented
for any unsupported functionality (section 9.3.1)
- MUST expose only data types defined in OData-CSDLXML
- MUST NOT require clients to understand any metadata or instance annotations (section 6.4), custom headers (section 6.5), or custom content (section 6.2) in the payload in order to correctly consume the service
-- MUST NOT violate any OData update semantics (section 11.4 and all subsections)
+- MUST NOT violate any OData update semantics (section 11.4 and all subsections)
- MUST NOT violate any other OData-defined semantics
-- SHOULD support
$expand
(section 11.2.5.2)
+- SHOULD support
$expand
(section 11.2.5.2)
- SHOULD publish metadata at
$metadata
according to OData-CSDLXML and MAY publish metadata according to OData-CSDLJSON (section 11.1.2)
- MUST support prefixed variants of supported headers and preference values
- MUST support enumeration and duration literals in URLs with the type prefix
@@ -2700,8 +2700,8 @@ section 11.2.6.6)
- MUST support batch requests according to the multipart format (section 11.7 and all subsections) and MAY support batch requests according to the JSON Batch format defined in OData-JSON
- MUST support the resource path conventions defined in OData-URL
-- SHOULD support asynchronous requests (section 11.6)
-- SHOULD support Delta change tracking (section 11.3)
+- SHOULD support asynchronous requests (section 11.6)
+- SHOULD support Delta change tracking (section 11.3)
- SHOULD support cross-join queries defined in OData-URL
- MAY support the
$compute
system query option (section 11.2.5.3)
diff --git a/docs/odata-protocol/odata-protocol.md b/docs/odata-protocol/odata-protocol.md
index d2511615a..55a727c79 100644
--- a/docs/odata-protocol/odata-protocol.md
+++ b/docs/odata-protocol/odata-protocol.md
@@ -2691,7 +2691,7 @@ key value(s), as described in [OData-URL](#ODataURL).
The set of structural or navigation properties to return may be
specified through [`$select`](#SystemQueryOptionselect) or
-[`$expand`](#SystemQueryOptionexpand)system query options.
+[`$expand`](#SystemQueryOptionexpand) system query options.
Clients MUST be prepared to receive additional properties in an entity
or complex type instance that are not advertised in metadata, even for
@@ -6334,33 +6334,33 @@ their intended scenario.
In order to conform to the OData 4.0 Minimal conformance level, a
service:
-1. MUST publish a [service document](#ServiceDocumentRequest) at the
+1. MUST publish a service document at the
service root ([section 11.1.1](#ServiceDocumentRequest))
2. MUST return data according to the [OData-JSON](#ODataJSON) format
-3. MUST use [server-driven paging](#ServerDrivenPaging) when returning
+3. MUST use server-driven paging when returning
partial results ([section 11.2.6.7](#ServerDrivenPaging)) and not use any other mechanism
-4. MUST return the appropriate [`OData-Version`](#HeaderODataVersion)
+4. MUST return the appropriate `OData-Version`
header ([section 8.1.5](#HeaderODataVersion))
5. MUST conform to the semantics the following headers, or fail the
request
- 1. [`Accept`](#HeaderAccept) ([section 8.2.1](#HeaderAccept))
- 2. [`OData-MaxVersion`](#HeaderODataMaxVersion) ([section 8.2.7](#HeaderODataMaxVersion))
-6. MUST follow OData guidelines for [extensibility](#Extensibility)
+ 1. `Accept` ([section 8.2.1](#HeaderAccept))
+ 2. `OData-MaxVersion` ([section 8.2.7](#HeaderODataMaxVersion))
+6. MUST follow OData guidelines for extensibility
([section 6](#Extensibility) and all subsections)
7. MUST successfully parse the request according to
[OData-ABNF](#ODataABNF) for any supported system query options and
either follow the specification or return
-[`501 Not Implemented`](#ResponseCode501NotImplemented) for any
+`501 Not Implemented` for any
unsupported functionality ([section 9.3.1](#ResponseCode501NotImplemented))
8. MUST expose only data types defined in [OData-CSDLXML](#ODataCSDL)
9. MUST NOT require clients to understand any metadata or instance
annotations ([section 6.4](#VocabularyExtensibility)), custom headers ([section 6.5](#HeaderFieldExtensibility)), or custom
content ([section 6.2](#PayloadExtensibility)) in the payload in order to correctly consume the
service
-10. MUST NOT violate any OData [update semantics](#DataModification)
+10. MUST NOT violate any OData update semantics
([section 11.4](#DataModification) and all subsections)
11. MUST NOT violate any other OData-defined semantics
-12. SHOULD support [`$expand`](#SystemQueryOptionexpand) ([section 11.2.5.2](#SystemQueryOptionexpand))
+12. SHOULD support `$expand` ([section 11.2.5.2](#SystemQueryOptionexpand))
13. SHOULD publish metadata at `$metadata` according to
[OData-CSDLXML](#ODataCSDL) and MAY publish metadata according to
[OData-CSDLJSON](#ODataCSDL) ([section 11.1.2](#MetadataDocumentRequest))
@@ -6490,9 +6490,9 @@ properties
according to the JSON Batch format defined in [OData-JSON](#ODataJSON)
12. MUST support the resource path conventions defined in
[OData-URL](#ODataURL)
-13. SHOULD support [asynchronous requests](#AsynchronousRequests)
+13. SHOULD support asynchronous requests
([section 11.6](#AsynchronousRequests))
-14. SHOULD support [Delta change tracking](#RequestingChanges) ([section 11.3](#RequestingChanges))
+14. SHOULD support Delta change tracking ([section 11.3](#RequestingChanges))
15. SHOULD support cross-join queries defined in [OData-URL](#ODataURL)
16. MAY support the `$compute` system query option ([section 11.2.5.3](#SystemQueryOptioncompute))
diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html
index ac8094874..acc533eb6 100644
--- a/docs/odata-url-conventions/odata-url-conventions.html
+++ b/docs/odata-url-conventions/odata-url-conventions.html
@@ -718,7 +718,7 @@ 4.9 Addressing a Member within an Entity Collection
Collections of entities are modeled as entity sets, collection-valued navigation properties, or operation results.
For entity sets, results of operations associated with an entity set through an EntitySet
or EntitySetPath
declaration, or collection-valued navigation properties with a NavigationPropertyBinding
or ContainsTarget=true
specification, members of the collection can be addressed by convention by appending the parenthesized key to the URL specifying the collection of entities, or by using the key-as-segment convention if supported by the service.
-For collection-valued navigation properties with navigation property bindings that end in a type-cast segment, a type-cast segment MUST be appended to the collection URL before appending the key segment.
+For collection-valued navigation properties with navigation property bindings that end in a type-cast segment, a type-cast segment MUST be appended to the collection URL before appending the key segment.
Note: entity sets or collection-valued navigation properties annotated with the term Capabilities.IndexableByKey
defined in OData-VocCap and a value of false
do not support addressing their members by key.
4.10 Addressing a Member of an Ordered Collection
Collections can be annotated as ordered using the Core.Ordered
term (see OData-VocCore). Individual items within an ordered collection of primitive or complex types can be addressed by appending a segment containing the zero-based ordinal to the URL of the collection. A negative ordinal number indexes from the end of the collection, with -1
representing the last item in the collection. Services MUST NOT specify a negative index when returning the address of a member of an ordered collection.
@@ -777,7 +777,7 @@ 4.13 Addressing Each Member of a Collection
To apply a PATCH
or DELETE
request to each member of a collection, clients append the path segment /$each
to a resource path identifying a collection.
-To apply a bound action or function to each member of a collection, clients append the path segment /$each
followed by a path segment identifying the bound action or function. The response is a collection of instances of the result type of the bound operation. If the bound operation returns a collection, the response is a collection of collections. System query options applied to the response can use $it
to reference an item in the outermost collection, followed by /any
, /all
, or /$count
.
+To apply a bound action or function to each member of a collection, clients append the path segment /$each
followed by a path segment identifying the bound action or function. The response is a collection of instances of the result type of the bound operation. If the bound operation returns a collection, the response is a collection of collections. System query options applied to the response can use $it
to reference an item in the outermost collection, followed by /any
, /all
, or /$count
.
The resource path of the collection preceding /$each
MAY contain type-cast segments or filter path segments to subset the collection.
4.14 Addressing the Media Stream of a Media Entity
To address the media stream represented by a media entity, clients append /$value
to the resource path of the media entity URL. Services may redirect from this canonical URL to the source URL of the media stream.
diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md
index a54cc2983..dfd77bfa7 100644
--- a/docs/odata-url-conventions/odata-url-conventions.md
+++ b/docs/odata-url-conventions/odata-url-conventions.md
@@ -1104,7 +1104,7 @@ supported by the service.
For collection-valued navigation properties with navigation property
bindings that end in a [type-cast segment](#AddressingDerivedTypes),
-a [type-cast segment](#AddressingDerivedTypes) MUST be
+a type-cast segment MUST be
appended to the collection URL before appending the key segment.
Note: entity sets or collection-valued navigation properties annotated
@@ -1283,7 +1283,7 @@ a collection.
To apply a [bound action](#AddressingActions) or function to each member
of a collection, clients append the path segment `/$each` followed by a
-path segment identifying the [bound action](#AddressingActions) or
+path segment identifying the bound action or
function. The response is a collection of instances of the result type
of the bound operation. If the bound operation returns a collection, the
response is a collection of collections. System query options applied to
diff --git a/odata-csdl/1 Introduction.md b/odata-csdl/1 Introduction.md
index 56382ae3a..4705b36bb 100644
--- a/odata-csdl/1 Introduction.md
+++ b/odata-csdl/1 Introduction.md
@@ -486,7 +486,7 @@ parameter or return type of an [action](#Action) or
underlying type is `Edm.Stream`, cannot be used in collections or for
non-binding parameters to functions or actions.
-Some of these types allow [facets](#TypeFacets), defined in section
+Some of these types allow facets, defined in section
"[Type Facets](#TypeFacets)".
See rule `primitiveLiteral` in [OData-ABNF](#ODataABNF) for the
diff --git a/odata-json-format/20 Instance Annotations.md b/odata-json-format/20 Instance Annotations.md
index 26a9fb628..14f626902 100644
--- a/odata-json-format/20 Instance Annotations.md
+++ b/odata-json-format/20 Instance Annotations.md
@@ -243,7 +243,7 @@ the client has specified the
`continue-on-error` preference. In
this case, the service MUST include a
[`nextLink`](#ControlInformationnextLinkodatanextLink).
-The [`nextLink`](#ControlInformationnextLinkodatanextLink) can be used to attempt retrieving the remaining members of the collection and could return an error indicating that the remaining
+The `nextLink` can be used to attempt retrieving the remaining members of the collection and could return an error indicating that the remaining
members are not available.
-------
diff --git a/odata-protocol/11 Data Service Requests.md b/odata-protocol/11 Data Service Requests.md
index 20ecf449b..b5afa982e 100644
--- a/odata-protocol/11 Data Service Requests.md
+++ b/odata-protocol/11 Data Service Requests.md
@@ -157,7 +157,7 @@ key value(s), as described in [OData-URL](#ODataURL).
The set of structural or navigation properties to return may be
specified through [`$select`](#SystemQueryOptionselect) or
-[`$expand`](#SystemQueryOptionexpand)system query options.
+[`$expand`](#SystemQueryOptionexpand) system query options.
Clients MUST be prepared to receive additional properties in an entity
or complex type instance that are not advertised in metadata, even for
diff --git a/odata-protocol/12 Conformance.md b/odata-protocol/12 Conformance.md
index 0d163b640..f57a0b396 100644
--- a/odata-protocol/12 Conformance.md
+++ b/odata-protocol/12 Conformance.md
@@ -44,33 +44,33 @@ their intended scenario.
In order to conform to the OData 4.0 Minimal conformance level, a
service:
-1. MUST publish a [service document](#ServiceDocumentRequest) at the
+1. MUST publish a service document at the
service root ([section ##ServiceDocumentRequest])
2. MUST return data according to the [OData-JSON](#ODataJSON) format
-3. MUST use [server-driven paging](#ServerDrivenPaging) when returning
+3. MUST use server-driven paging when returning
partial results ([section ##ServerDrivenPaging]) and not use any other mechanism
-4. MUST return the appropriate [`OData-Version`](#HeaderODataVersion)
+4. MUST return the appropriate `OData-Version`
header ([section ##HeaderODataVersion])
5. MUST conform to the semantics the following headers, or fail the
request
- 1. [`Accept`](#HeaderAccept) ([section ##HeaderAccept])
- 2. [`OData-MaxVersion`](#HeaderODataMaxVersion) ([section ##HeaderODataMaxVersion])
-6. MUST follow OData guidelines for [extensibility](#Extensibility)
+ 1. `Accept` ([section ##HeaderAccept])
+ 2. `OData-MaxVersion` ([section ##HeaderODataMaxVersion])
+6. MUST follow OData guidelines for extensibility
([section ##Extensibility] and all subsections)
7. MUST successfully parse the request according to
[OData-ABNF](#ODataABNF) for any supported system query options and
either follow the specification or return
-[`501 Not Implemented`](#ResponseCode501NotImplemented) for any
+`501 Not Implemented` for any
unsupported functionality ([section ##ResponseCode501NotImplemented])
8. MUST expose only data types defined in [OData-CSDLXML](#ODataCSDL)
9. MUST NOT require clients to understand any metadata or instance
annotations ([section ##VocabularyExtensibility]), custom headers ([section ##HeaderFieldExtensibility]), or custom
content ([section ##PayloadExtensibility]) in the payload in order to correctly consume the
service
-10. MUST NOT violate any OData [update semantics](#DataModification)
+10. MUST NOT violate any OData update semantics
([section ##DataModification] and all subsections)
11. MUST NOT violate any other OData-defined semantics
-12. SHOULD support [`$expand`](#SystemQueryOptionexpand) ([section ##SystemQueryOptionexpand])
+12. SHOULD support `$expand` ([section ##SystemQueryOptionexpand])
13. SHOULD publish metadata at `$metadata` according to
[OData-CSDLXML](#ODataCSDL) and MAY publish metadata according to
[OData-CSDLJSON](#ODataCSDL) ([section ##MetadataDocumentRequest])
@@ -200,9 +200,9 @@ properties
according to the JSON Batch format defined in [OData-JSON](#ODataJSON)
12. MUST support the resource path conventions defined in
[OData-URL](#ODataURL)
-13. SHOULD support [asynchronous requests](#AsynchronousRequests)
+13. SHOULD support asynchronous requests
([section ##AsynchronousRequests])
-14. SHOULD support [Delta change tracking](#RequestingChanges) ([section ##RequestingChanges])
+14. SHOULD support Delta change tracking ([section ##RequestingChanges])
15. SHOULD support cross-join queries defined in [OData-URL](#ODataURL)
16. MAY support the `$compute` system query option ([section ##SystemQueryOptioncompute])
diff --git a/odata-url-conventions/4 Resource Path.md b/odata-url-conventions/4 Resource Path.md
index 41786fcc2..373d7ec8c 100644
--- a/odata-url-conventions/4 Resource Path.md
+++ b/odata-url-conventions/4 Resource Path.md
@@ -655,7 +655,7 @@ supported by the service.
For collection-valued navigation properties with navigation property
bindings that end in a [type-cast segment](#AddressingDerivedTypes),
-a [type-cast segment](#AddressingDerivedTypes) MUST be
+a type-cast segment MUST be
appended to the collection URL before appending the key segment.
Note: entity sets or collection-valued navigation properties annotated
@@ -834,7 +834,7 @@ a collection.
To apply a [bound action](#AddressingActions) or function to each member
of a collection, clients append the path segment `/$each` followed by a
-path segment identifying the [bound action](#AddressingActions) or
+path segment identifying the bound action or
function. The response is a collection of instances of the result type
of the bound operation. If the bound operation returns a collection, the
response is a collection of collections. System query options applied to
From e002f3c3ff1cf66f2ff80c65707b6ac9c76ccf4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?=
Date: Mon, 4 Dec 2023 15:00:52 +0100
Subject: [PATCH 21/22] Whitespace clean-up (#199)
---
docs/odata-csdl-json/odata-csdl-json.html | 2 +-
docs/odata-csdl-json/odata-csdl-json.md | 6 +-
docs/odata-csdl-xml/odata-csdl-xml.md | 7 +-
docs/odata-json-format/odata-json-format.html | 7 +-
docs/odata-json-format/odata-json-format.md | 108 ++-
docs/odata-protocol/odata-protocol.html | 243 ++---
docs/odata-protocol/odata-protocol.md | 233 ++---
.../odata-temporal-ext.html | 880 ++++++++---------
docs/odata-temporal-ext/odata-temporal-ext.md | 888 +++++++++---------
.../odata-url-conventions.html | 4 +-
.../odata-url-conventions.md | 33 +-
odata-csdl/1 Introduction.md | 4 +-
odata-csdl/14 Vocabulary and Annotation.md | 2 +-
odata-csdl/Appendix.md | 2 +-
odata-json-format/10 Media Entity.md | 20 +-
odata-json-format/16 Bound Function.md | 12 +-
.../19 Batch Requests and Responses.md | 14 +-
odata-json-format/20 Instance Annotations.md | 4 +-
odata-json-format/23 Conformance.md | 2 +-
.../3 Requesting the JSON Format.md | 2 +-
odata-json-format/4 Common Characteristics.md | 2 +-
odata-json-format/5 Service Document.md | 4 +-
odata-json-format/7 Structural Property.md | 32 +-
odata-json-format/Appendix.md | 6 +-
odata-protocol/10 Context URL.md | 10 +-
odata-protocol/11 Data Service Requests.md | 16 +-
odata-protocol/11.4 Data Modification.md | 122 +--
odata-protocol/11.5 Operations.md | 54 +-
odata-protocol/11.7 Batch Requests.md | 10 +-
odata-protocol/12 Conformance.md | 2 +-
odata-protocol/8 Header Fields.md | 8 +-
odata-protocol/Appendix.md | 4 +-
odata-temporal-ext/1 Introduction.md | 2 +-
odata-temporal-ext/2 Overview.md | 2 +-
odata-temporal-ext/3 Vocabulary.md | 116 +--
odata-temporal-ext/4 Temporal Requests.md | 432 ++++-----
.../4.3 Modifying Temporal Data.md | 324 +++----
odata-temporal-ext/Appendix.md | 10 +-
odata-url-conventions/1 Introduction.md | 2 +-
odata-url-conventions/4 Resource Path.md | 2 +-
odata-url-conventions/5 Query Options.md | 19 +-
odata-url-conventions/Appendix.md | 4 +-
42 files changed, 1848 insertions(+), 1808 deletions(-)
diff --git a/docs/odata-csdl-json/odata-csdl-json.html b/docs/odata-csdl-json/odata-csdl-json.html
index a9c07777f..e6e202a4c 100644
--- a/docs/odata-csdl-json/odata-csdl-json.html
+++ b/docs/odata-csdl-json/odata-csdl-json.html
@@ -3262,7 +3262,7 @@ $UrlRef
"$Function": "odata.fillUriTemplate"
}
},
-
+
"@Core.LongDescription#element": {
"$UrlRef": "http://host/wiki/HowToUse"
}
diff --git a/docs/odata-csdl-json/odata-csdl-json.md b/docs/odata-csdl-json/odata-csdl-json.md
index 930dbbef3..94e059bdc 100644
--- a/docs/odata-csdl-json/odata-csdl-json.md
+++ b/docs/odata-csdl-json/odata-csdl-json.md
@@ -622,7 +622,9 @@ responses.
The facets in the following subsections modify or constrain the acceptable values of primitive typed model elements,
for example a [structural property](#StructuralProperty),
-action or function [parameter](#Parameter), action or function [return type](#ReturnType), or [term](#Term).
+action or function [parameter](#Parameter),
+action or function [return type](#ReturnType), or
+[term](#Term).
For single-valued model elements the facets apply to the value of the
model element. For collection-valued model elements the facets apply to the items
@@ -5469,7 +5471,7 @@ Example 88:
"$Function": "odata.fillUriTemplate"
}
},
-
+
"@Core.LongDescription#element": {
"$UrlRef": "http://host/wiki/HowToUse"
}
diff --git a/docs/odata-csdl-xml/odata-csdl-xml.md b/docs/odata-csdl-xml/odata-csdl-xml.md
index c2b36f72e..8e5e9d69f 100644
--- a/docs/odata-csdl-xml/odata-csdl-xml.md
+++ b/docs/odata-csdl-xml/odata-csdl-xml.md
@@ -562,7 +562,9 @@ responses.
The facets in the following subsections modify or constrain the acceptable values of primitive typed model elements,
for example a [structural property](#StructuralProperty),
-action or function [parameter](#Parameter), action or function [return type](#ReturnType), or [term](#Term).
+action or function [parameter](#Parameter),
+action or function [return type](#ReturnType), or
+[term](#Term).
For single-valued model elements the facets apply to the value of the
model element. For collection-valued model elements the facets apply to the items
@@ -5673,7 +5675,8 @@ http://www.w3.org/TR/2008/REC-xml-20081126/. Latest version available at http://
###### [XML-Base]
_XML Base (Second Edition)_. J. Marsh, R. Tobin, Editors, W3C Recommendation, 28 January 2009.
-http://www.w3.org/TR/2009/REC-xmlbase-20090128/. Latest version available at http://www.w3.org/TR/xmlbase/.
+http://www.w3.org/TR/2009/REC-xmlbase-20090128/. Latest version available at http://www.w3.org/TR/xmlbase/.
+
###### [XML-Schema-1]
_W3C XML Schema Definition Language (XSD) 1.1 Part 1: Structures_. D. Beech, M. Maloney, C. M. Sperberg-McQueen, H. S. Thompson, S. Gao, N. Mendelsohn, Editors, W3C Recommendation, 5 April 2012.
http://www.w3.org/TR/2012/REC-xmlschema11-1-20120405/. Latest version available at http://www.w3.org/TR/xmlschema11-1/.
diff --git a/docs/odata-json-format/odata-json-format.html b/docs/odata-json-format/odata-json-format.html
index e829a010e..9396eed9e 100644
--- a/docs/odata-json-format/odata-json-format.html
+++ b/docs/odata-json-format/odata-json-format.html
@@ -404,7 +404,7 @@ 3.2 Controlling the Representation of Numbers
The IEEE754Compatible=true
format parameter indicates that the service MUST serialize Edm.Int64
and Edm.Decimal
numbers (including the count
, if requested) as strings. This is in conformance with RFC7493.
If not specified, or specified as IEEE754Compatible=false
, all numbers MUST be serialized as JSON numbers.
-This enables support for JavaScript numbers that are defined to be 64-bit binary format IEEE 754 values (see [ECMAScript, section 4.3.1.9]) resulting in integers losing precision past 15 digits, and decimals losing precision due to the conversion from base 10 to base 2.
+This enables support for JavaScript numbers that are defined to be 64-bit binary format IEEE 754 values (see ECMAScript, section 4.3.1.9) resulting in integers losing precision past 15 digits, and decimals losing precision due to the conversion from base 10 to base 2.
OData JSON request and response payloads that format Edm.Int64
and Edm.Decimal
values as strings MUST specify this format parameter in the media type sent in the Content-Type
header.
Services producing responses without format parameter IEEE754Compatible=true
which are unable to produce exact JSON numbers MAY serialize Edm.Int64
and Edm.Decimal
numbers with a rounded/inexact value as a JSON number and annotate that value with an instance annotation with term Core.ValueException
defined in OData-VocCore containing the exact value as a string. This situation can for example happen if the client only accepts application/json
without any format parameters and the service is written in JavaScript.
For payloads with an OData-Version
header equal to 4.0
the ExponentialDecimals=true
format parameter indicates that the service MAY serialize Edm.Decimal
numbers in exponential notation (e.g. 1e-6
instead of 0.000001
).
@@ -989,7 +989,8 @@ 9 Str
10 Media Entity
-Media entities are entities that describe a media resource, for example a photo. They are represented as entities that contain additional media*
control information. If the actual stream data for the media entity is included, it is represented as property named $value
whose string value is the base64url-encoded value of the media stream, see RFC4648.
+Media entities are entities that describe a media resource, for example a photo. They are represented as entities that contain additional media*
control information.
+If the actual stream data for the media entity is included, it is represented as property named $value
whose string value is the base64url-encoded value of the media stream, see RFC4648.
Example 25:
{
@@ -2154,7 +2155,7 @@ [RFC8174]
[RFC8259]
Bray, T., Ed., “The JavaScript Object Notation (JSON) Data Interchange Format”, STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017. https://www.rfc-editor.org/info/rfc8259.
A.2 Informative References
-[ECMAScript]
+[ECMAScript]
ECMAScript 2023 Language Specification, 14th Edition, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
Appendix B. Safety, Security and Privacy Considerations
diff --git a/docs/odata-json-format/odata-json-format.md b/docs/odata-json-format/odata-json-format.md
index 8c23db484..7494a17d0 100644
--- a/docs/odata-json-format/odata-json-format.md
+++ b/docs/odata-json-format/odata-json-format.md
@@ -492,7 +492,7 @@ If not specified, or specified as `IEEE754Compatible=false`,
all numbers MUST be serialized as JSON numbers.
This enables support for JavaScript numbers that are defined to be
-64-bit binary format IEEE 754 values (see **[[ECMAScript](#ECMAScript), [section 4.3.1.9](http://www.ecma-international.org/ecma-262/5.1/#sec-4.3.19)]**)
+64-bit binary format IEEE 754 values (see [ECMAScript](#_ECMAScript), [section 4.3.1.9](http://www.ecma-international.org/ecma-262/5.1/#sec-4.3.19))
resulting in integers losing precision past 15 digits, and decimals
losing precision due to the conversion from base 10 to base 2.
@@ -565,7 +565,8 @@ parameter if `Edm.Int64` and `Edm.Decimal` numbers
are represented as strings.
Requests and responses MAY add the `streaming` parameter with
-a value of `true` or `false`, see section "[Payload Ordering Constraints](#PayloadOrderingConstraints)".
+a value of `true` or `false`, see section
+"[Payload Ordering Constraints](#PayloadOrderingConstraints)".
## 4.2 Message Body
@@ -1224,7 +1225,7 @@ Service documents MAY contain [annotations](#InstanceAnnotations) in
any of its JSON objects. Services MUST NOT produce name/value pairs
other than the ones explicitly defined in this section, and clients MUST
ignore unknown name/value pairs.
-
+
::: example
Example 9:
```json
@@ -1286,7 +1287,7 @@ An entity representation can be (modified and) round-tripped to the
service directly. The [context
URL](#ControlInformationcontextodatacontext) is used in requests only
as a base for [relative URLs](#RelativeURLs).
-
+
::: example
Example 10: entity with `metadata=minimal`
```json
@@ -1341,7 +1342,8 @@ Example 11: entity with `metadata=full`
A property within an entity or complex type instance is represented as a
name/value pair. The name MUST be the name of the property; a non-null value is
-represented depending on its type as a [primitive value](#PrimitiveValue), a [complex value](#ComplexValue), a
+represented depending on its type as a [primitive value](#PrimitiveValue),
+a [complex value](#ComplexValue), a
[collection of primitive values](#CollectionofPrimitiveValues), or
a [collection of complex values](#CollectionofComplexValues).
@@ -1366,7 +1368,8 @@ Values of type `Edm.String` are represented as JSON strings,
using the JSON string escaping rules.
Values of type `Edm.Binary`, `Edm.Date`,
-`Edm.DateTimeOffset`, `Edm.Duration`, `Edm.Guid`, and `Edm.TimeOfDay` are represented as
+`Edm.DateTimeOffset`, `Edm.Duration`,
+`Edm.Guid`, and `Edm.TimeOfDay` are represented as
JSON strings whose content satisfies the rules `binaryValue`,
`dateValue`, `dateTimeOffsetValue`,
`durationValue`, `guidValue`, and
@@ -1395,7 +1398,7 @@ payload. Whether the value represents a geography type or geometry type
is inferred from its usage or specified using the
[`type`](#ControlInformationtypeodatatype)
control information.
-
+
::: example
Example 12:
```json
@@ -1428,7 +1431,7 @@ name/value pair for each property that makes up the complex type. Each
property value is formatted as appropriate for the type of the property.
It MAY have name/value pairs for [instance annotations](#InstanceAnnotations) and control information.
-
+
::: example
Example 13:
```json
@@ -1456,7 +1459,7 @@ element in the array is the representation of a [primitive
value](#PrimitiveValue). A JSON literal `null` represents
a null value within the collection. An empty collection is represented
as an empty array.
-
+
::: example
Example 14: partial collection of strings with next link
```json
@@ -1481,7 +1484,7 @@ depending on the JavaScript type.
A collection of complex values is represented as a JSON array; each
element in the array is the representation of a [complex value](#ComplexValue). A JSON literal `null` represents a
null value within the collection. An empty collection is represented as an empty array.
-
+
::: example
Example 15: partial collection of complex values with next link
```json
@@ -1549,7 +1552,7 @@ client requests `metadata=full` or the navigation link cannot
be computed, e.g. if it is within a collection of complex type
instances. If it is represented it MUST immediately precede the expanded
navigation property if the latter is represented.
-
+
::: example
Example 16:
```json
@@ -1576,7 +1579,7 @@ cannot be computed by appending `/$ref` to the navigation
link. If it is represented, it MUST immediately precede the navigation
link if the latter is represented, otherwise it MUST immediately precede
the expanded navigation property if it is represented.
-
+
::: example
Example 17:
```json
@@ -1610,7 +1613,7 @@ represented as an empty JSON array. The navigation property MAY include
[`nextLink`](#ControlInformationnextLinkodatanextLink) control information. If a navigation property is
expanded with the suffix `/$count`, only the
[`count`](#ControlInformationcountodatacount) control information is represented.
-
+
::: example
Example 18:
```json
@@ -1632,7 +1635,7 @@ new entities MAY be specified using the same representation as for an
Deep inserts are not allowed in update operations using `PUT`
or `PATCH` requests.
-
+
::: example
Example 19: inserting a new order for a new customer with order items
related to existing products:
@@ -1673,7 +1676,7 @@ the navigation property it belongs to and has a single value for
single-valued navigation properties or an array of values for collection
navigation properties. For nullable single-valued navigation properties
the value `null` may be used to remove the relationship.
-
+
::: example
Example 20: assign an existing product to an existing category with a
partial update request against the product
@@ -1694,7 +1697,7 @@ For requests containing an `OData-Version` header with a value
of `4.01`, a relationship is bound to an existing entity
using the same representation as for an [expanded entity
reference](#EntityReference).
-
+
::: example
Example 21: assign an existing product to an existing category with a
partial update request against the product
@@ -1707,7 +1710,7 @@ Content-Type: application/json
}
```
:::
-
+
::: example
Example 22: submit a partial update request to:
- modify the name of an existing category
@@ -1742,7 +1745,8 @@ Content-Type: application/json
OData 4.01 services MUST support both the OData 4.0 representation, for
requests containing an `OData-Version` header with a value of
`4.0`, and the OData 4.01 representation, for requests
-containing an `OData-Version` header with a value of `4.01`. Clients MUST NOT use `@odata.bind` in requests with an
+containing an `OData-Version` header with a value of `4.01`.
+Clients MUST NOT use `@odata.bind` in requests with an
`OData-Version` header with a value of `4.01`.
For insert operations collection navigation property bind operations and
@@ -1763,7 +1767,7 @@ that can be used in a subsequent request to determine if the collection
has changed.
Services MAY include this control information as appropriate.
-
+
::: example
Example 23: ETag for a collection of related entities
```json
@@ -1816,7 +1820,7 @@ If the included stream property has no value, the non-existing stream
data is represented as `null` and the control information
[`mediaContentType`](#ControlInformationmediaodatamedia)
is not necessary.
-
+
::: example
Example 24:
```json
@@ -1840,11 +1844,12 @@ Example 24:
Media entities are entities that describe a media resource, for example
a photo. They are represented as entities that contain additional
-[`media*`](#ControlInformationmediaodatamedia) control information.
+[`media*`](#ControlInformationmediaodatamedia) control information.
+
If the actual stream data for the media entity is included, it is
represented as property named `$value` whose
string value is the base64url-encoded value of the media stream, see [RFC4648](rfc4648).
-
+
::: example
Example 25:
```json
@@ -1883,7 +1888,7 @@ represented as an object with a single name/value pair whose name is
`value`. Its value is the JSON representation of a
[collection of complex type values](#CollectionofComplexValues) or
[collection of primitive values](#CollectionofPrimitiveValues).
-
+
::: example
Example 26: primitive value
```json
@@ -1893,7 +1898,7 @@ Example 26: primitive value
}
```
:::
-
+
::: example
Example 27: collection of primitive values
```json
@@ -1903,7 +1908,7 @@ Example 27: collection of primitive values
}
```
:::
-
+
::: example
Example 28: empty collection of primitive values
```json
@@ -1913,7 +1918,7 @@ Example 28: empty collection of primitive values
}
```
:::
-
+
::: example
Example 29: complex value
```json
@@ -1927,7 +1932,7 @@ Example 29: complex value
}
```
:::
-
+
::: example
Example 30: empty collection of complex values
```json
@@ -2035,7 +2040,8 @@ entity and MAY contain the [`type`](#ControlInformationtypeodatatype)
control information and [instance annotations](#InstanceAnnotations), but no additional properties or
control information.
-A collection of entity references is represented as a [collection of entities](#CollectionofEntities), with entity reference representations instead of entity representations as items in the array value of the `value` name/value pair.
+A collection of entity references is represented as a [collection of entities](#CollectionofEntities),
+with entity reference representations instead of entity representations as items in the array value of the `value` name/value pair.
The outermost JSON object in a response MUST contain a
[`context`](#ControlInformationcontextodatacontext)
@@ -2043,7 +2049,7 @@ control information and MAY contain
[`count`](#ControlInformationcountodatacount),
[`nextLink`](#ControlInformationnextLinkodatanextLink), or
[`deltaLink`](#ControlInformationdeltaLinkodatadeltaLink) control information.
-
+
::: example
Example 31: entity reference to order 10643
```json
@@ -2053,7 +2059,7 @@ Example 31: entity reference to order 10643
}
```
:::
-
+
::: example
Example 32: collection of entity references
```json
@@ -2771,7 +2777,7 @@ title as a string.
If [`metadata=minimal`](#metadataminimalodatametadataminimal)
is requested, the `target` name/value pair MUST be included
if its value differs from the canonical function or action URL.
-
+
::: example
Example 40: minimal representation of a function where all overloads are
applicable
@@ -2783,7 +2789,7 @@ applicable
}
```
:::
-
+
::: example
Example 41: full representation of a specific overload with parameter
alias for the `Year` parameter
@@ -2798,7 +2804,7 @@ alias for the `Year` parameter
}
```
:::
-
+
::: example
Example 42: full representation in a collection
```json
@@ -2875,7 +2881,7 @@ title as a string.
If [`metadata=minimal`](#metadataminimalodatametadataminimal)
is requested, the `target` name/value pair MUST be included
if its value differs from the canonical function or action URL.
-
+
::: example
Example 44: minimal representation in an entity
```json
@@ -2886,7 +2892,7 @@ Example 44: minimal representation in an entity
}
```
:::
-
+
::: example
Example 45: full representation in an entity:
```json
@@ -2900,7 +2906,7 @@ Example 45: full representation in an entity:
}
```
:::
-
+
::: example
Example 46: full representation in a collection
```json
@@ -3102,7 +3108,7 @@ A `body` MUST NOT be specified if the `method` is `get` or `delete`.
The request object and the `headers` object MUST NOT contain name/value pairs with duplicate names.
This is in conformance with [RFC7493](#rfc7493).
-
+
::: example
Example 48: a batch request that contains
the following individual requests in the order listed
@@ -3165,7 +3171,7 @@ The entity returned by a preceding request can be referenced in the
request URL of subsequent requests. If the `Location` header in the response
contains a relative URL, clients MUST be able to resolve it relative to the
request's URL even if that contains such a reference.
-
+
::: example
Example 49: a batch request that contains the following operations in
the order listed:
@@ -3307,7 +3313,8 @@ same value.
If any response within an atomicity group returns a failure code, all
requests within that atomicity group are considered failed, regardless
-of their individual returned status code. The service MAY return `424 Failed Dependency` for statements
+of their individual returned status code. The service MAY return
+`424 Failed Dependency` for statements
within an atomicity group that fail or are not attempted due to other
failures within the same atomicity group.
@@ -3332,7 +3339,7 @@ Relative URLs in a response object follow the rules for [relative
URLs](#RelativeURLs) based on the request URL of the corresponding
request. Especially: URLs in responses MUST NOT contain
`$`-prefixed request identifiers.
-
+
::: example
Example 51: referencing the batch request [example 48](#batchRequest) above, assume all
the requests except the final query request succeed. In this case the
@@ -3390,7 +3397,7 @@ control information in the JSON batch response, thus signaling that the
response is only a partial result. A subsequent `GET` request
to the next link MAY result in a `202 Accepted` response with a
`location` header pointing to a new status monitor resource.
-
+
::: example
Example 52: referencing the example 47 above again, assume that the
request is sent with the `respond-async` preference. This
@@ -3480,7 +3487,7 @@ the service responds with a JSON batch response. In this case the
asynchronously executed individual request with a `status` of
`202`, a `location` header pointing to an
individual status monitor resource, and optionally a `retry-after` header.
-
+
::: example
Example 53: the first individual request is processed asynchronously,
the second synchronously, the batch itself is processed synchronously
@@ -3506,7 +3513,8 @@ Content-Type: application/json
]
}
```
-:::
+:::
+
-------
@@ -3652,7 +3660,7 @@ concerns around information disclosure.
Error responses MAY contain [annotations](#InstanceAnnotations) in
any of its JSON objects.
-
+
::: example
Example 55:
```json
@@ -3701,7 +3709,7 @@ header-appropriate way:
Unicode characters beyond `00FF` within JSON strings are
encoded as `\uXXXX` or `\uXXXX\uXXXX` (see
[RFC8259](#rfc8259), section 7)
-
+
::: example
Example 56: note that this is one HTTP header line without any line
breaks or optional whitespace
@@ -3777,7 +3785,7 @@ this version of the OData JSON Specification.
Conforming clients MUST be prepared to consume a service that uses any or all of the constructs defined in this specification. The exception to this are the constructs defined in Delta Response, which are only required for clients that request changes.
-
+
In order to be a conforming consumer of the OData JSON format, a client or service:
1. MUST either:
@@ -3926,9 +3934,11 @@ https://www.rfc-editor.org/info/rfc8174.
_Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017_.
https://www.rfc-editor.org/info/rfc8259.
-## A.2 Informative References
-###### [ECMAScript]
-_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
+## A.2 Informative References
+
+###### [ECMAScript]
+_ECMAScript 2023 Language Specification, 14th Edition_, June 2023. Standard ECMA-262.
+https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
-------
diff --git a/docs/odata-protocol/odata-protocol.html b/docs/odata-protocol/odata-protocol.html
index 984170c42..4aa67b28f 100644
--- a/docs/odata-protocol/odata-protocol.html
+++ b/docs/odata-protocol/odata-protocol.html
@@ -928,7 +928,7 @@ OData-Version
header) is format-specific and consists at least of the following information:
code
: required non-null, non-empty, language-independent string. Its value is a service-defined error code. This code serves as a sub-status for the HTTP error code specified in the response.
-message
: required non-null, non-empty, language-dependent, human-readable string describing the error. The Content-Language
header MUST contain the language code from RFC5646 corresponding to the language in which the value for message is written.
+message
: required non-null, non-empty, language-dependent, human-readable string describing the error. The Content-Language
header MUST contain the language code from RFC5646 corresponding to the language in which the value for message is written.
target
: optional nullable, potentially empty string indicating the target of the error, for example, the name of the property in error.
details
: optional, potentially empty collection of instances of structured types with code
, message
, and target
following the rules above.
innererror
: optional instance of structured type with service-defined content.
@@ -1077,9 +1077,9 @@
Example 22: resource URL and corresponding context URL — expand with $levels
http://host/service/Employees/Sales.Manager?$select=DirectReports
- &$expand=DirectReports($select=FirstName,LastName;$levels=4)
+ &$expand=DirectReports($select=FirstName,LastName;$levels=4)
http://host/service/$metadata
- #Employees/Sales.Manager(DirectReports,DirectReports+(FirstName,LastName))
+ #Employees/Sales.Manager(DirectReports,DirectReports+(FirstName,LastName))
10.10 Expanded Entity
Context URL template:
@@ -1093,9 +1093,9 @@ 10
Example 23: resource URL and corresponding context URL
http://host/service/Employees(1)/Sales.Manager?
- $expand=DirectReports($select=FirstName,LastName;$levels=4)
+ $expand=DirectReports($select=FirstName,LastName;$levels=4)
http://host/service/$metadata
- #Employees/Sales.Manager(DirectReports+(FirstName,LastName))/$entity
+ #Employees/Sales.Manager(DirectReports+(FirstName,LastName))/$entity
10.11 Collection of Entity References
Context URL template:
@@ -1175,7 +1175,7 @@ 10.19 $all
Response
Context URL template:
@@ -1387,9 +1387,9 @@
Example 45: compute total price for order items (line breaks only for readability)
GET http://host/service/Customers
- ?$filter=Orders/any(o:o/TotalPrice gt 100)
- &$expand=Orders($compute=Price mult Qty as TotalPrice
- ;$select=Name,Price,Qty,TotalPrice)
+ ?$filter=Orders/any(o:o/TotalPrice gt 100)
+ &$expand=Orders($compute=Price mult Qty as TotalPrice
+ ;$select=Name,Price,Qty,TotalPrice)
11.2.6 Querying Collections
OData services support querying collections of entities, complex type instances, and primitive values.
@@ -1644,12 +1644,12 @@ 11.2.10 Requesting the Number of Items in a Collection
To request only the number of items of a collection of entities or items of a collection-valued property, the client issues a GET
request with /$count
appended to the resource path of the collection.
-On success, the response body MUST contain the exact count of items matching the request after applying any $filter
or $search
system query options, formatted as a simple primitive integer value with media type text/plain
. Clients SHOULD NOT combine the system query options [ ]{.MsoCommentReference}$top
, $skip
, $orderby
, $expand
, and $format
with the path suffix /$count
. The result of such a request is undefined.
+On success, the response body MUST contain the exact count of items matching the request after applying any $filter
or $search
system query options, formatted as a simple primitive integer value with media type text/plain
. Clients SHOULD NOT combine the system query options $top
, $skip
, $orderby
, $expand
, and $format
with the path suffix /$count
. The result of such a request is undefined.
Example 69: return the number of products in the Products entity set
GET http://host/service/Products/$count
@@ -1708,7 +1708,8 @@ 11.3.1 Delta L
If the defining query contains a $schemaversion
system query option, the response MUST be represented according to that schema version.
If the defining query contains a $filter
or $search
, the response MUST include only changes to entities matching the specified criteria. Added entities MUST be returned for entities that were added or changed and now match the specified criteria, and deleted entities MUST be returned for entities that are changed to no longer match the criteria of $filter
or $search
.
The delta link MUST NOT encode any client top or skip value, and SHOULD NOT encode a request for an inline count.
-If the defining query includes expanded relationships, the delta link MUST return changes, additions, or deletions to the expanded entities, as well as added or deleted links to expanded entities or nested collections representing current membership. If the defining query includes expanded references, then the delta link MUST return changes to the membership in the set of expanded references. Navigation properties specified in the $select
list of a defining query are not used to define the scope or contents of the items being tracked. Clients can specify /$ref
in $expand
in order to specify interest in the set of related entities without interest in changes to the content of those related entities.
+If the defining query includes expanded relationships, the delta link MUST return changes, additions, or deletions to the expanded entities, as well as added or deleted links to expanded entities or nested collections representing current membership. If the defining query includes expanded references, then the delta link MUST return changes to the membership in the set of expanded references.
+Navigation properties specified in the $select
list of a defining query are not used to define the scope or contents of the items being tracked. Clients can specify /$ref
in $expand
in order to specify interest in the set of related entities without interest in changes to the content of those related entities.
If an expanded entity becomes orphaned because all paths to the entity as specified in the defining query have been broken (i.e. due to relationship changes and/or changes or deletions to parent entities) then the service MUST return the appropriate notifications for the client to determine that the entity has been orphaned (i.e. the changed relationships and removed parent entities). The client should not assume that it will receive additional notifications for such an orphaned entity.
Entities are considered changed if any of the structural properties have changed. Changes to related entities and to streams are not considered a change to the entity containing the stream or navigation property.
If the defining query contains a projection, the generated delta link SHOULD logically include the same projection, such that the delta query only includes fields specified in the projection. Services MAY use the projection to limit the entities returned to those that have changed within the selected fields, but the client MUST be prepared to receive entities returned whether or not the field that changed was specified in the projection.
@@ -1770,29 +1771,29 @@
Example 76: using the JSON format, 4.0 clients can create a new manager entity with links to an existing manager (of managers) and to two existing employees by applying the odata.bind
annotation to the Manager
and DirectReports
navigation properties
{
- "@odata.type": "#Northwind.Manager",
- "ID": 1,
- "FirstName": "Pat",
- "LastName": "Griswold",
+"@odata.type": "#Northwind.Manager",
+ "ID": 1,
+ "FirstName": "Pat",
+ "LastName": "Griswold",
"Manager@odata.bind": "http://host/service/Employees(0)",
- "DirectReports@odata.bind": [
- "http://host/service/Employees(5)",
- "http://host/service/Employees(6)"
- ]
+"DirectReports@odata.bind": [
+ "http://host/service/Employees(5)",
+ "http://host/service/Employees(6)"
+ ]
}
Example 77: using the JSON format, 4.01 clients can create a new manager entity with links to an existing manager (of managers) and to two existing employees by including the entity-ids within the Manager
and DirectReports
navigation properties
{
- "@type": "#Northwind.Manager",
- "ID": 1,
- "FirstName": "Pat",
- "LastName": "Griswold",
+"@type": "#Northwind.Manager",
+ "ID": 1,
+ "FirstName": "Pat",
+ "LastName": "Griswold",
"Manager": { "@id": "Employees(0)" },
- "DirectReports": [
- {"@id": "Employees(5)"},
- {"@id": "Employees(6)"}
- ]
+"DirectReports": [
+ {"@id": "Employees(5)"},
+ {"@id": "Employees(6)"}
+ ]
}
Upon successful completion of the operation, the service creates the requested entity and relates it to the requested existing entities.
@@ -1827,21 +1828,21 @@
Example 78: using the JSON format, a 4.01 PATCH
request can update a manager entity. Following the update, the manager has three direct reports; two existing employees and one new employee named Suzanne Brown
. The LastName
of employee 6 is updated to Smith
.
{
- "@type": "#Northwind.Manager",
- "FirstName" : "Patricia",
- "DirectReports": [
- {
- "@id": "Employees(5)"
- },
- {
- "@id": "Employees(6)",
- "LastName": "Smith"
- },
- {
- "FirstName": "Suzanne",
- "LastName": "Brown"
- }
- ]
+"@type": "#Northwind.Manager",
+ "FirstName": "Patricia",
+ "DirectReports": [
+ {
+ "@id": "Employees(5)"
+ },
+ {
+ "@id": "Employees(6)",
+ "LastName": "Smith"
+ },
+ {
+ "FirstName": "Suzanne",
+ "LastName": "Brown"
+ }
+ ]
}
If the nested collection is represented as a delta annotation on the navigation property, then the collection contains members to be added or changed and MAY include deleted entities for entities that are no longer part of the collection, using the delta payload format. If the deleted entity specifies a reason
as deleted
, then the entity is both removed from the collection and deleted, otherwise it is removed from the collection and only deleted if the relationship is contained. Non-key properties of the deleted entity are ignored. Nested collections MUST NOT contain added or deleted links. If the request contains nested delta collections, then the PATCH
verb must be specified.
@@ -1856,33 +1857,33 @@ {
- "@type": "#Northwind.Manager",
- "FirstName": "Patricia",
- "DirectReports@delta": [
- {
- "@removed": {
- "reason": "deleted"
- },
- "@id": "Employees(3)"
- },
- {
- "@removed": {
- "reason": "changed"
- },
- "@id": "Employees(4)"
- },
- {
- "@id": "Employees(5)"
- },
- {
- "@id": "Employees(6)",
- "LastName": "Smith"
- },
- {
- "FirstName": "Suzanne",
- "LastName": "Brown"
- }
- ]
+"@type": "#Northwind.Manager",
+ "FirstName": "Patricia",
+ "DirectReports@delta": [
+ {
+ "@removed": {
+ "reason": "deleted"
+ },
+ "@id": "Employees(3)"
+ },
+ {
+ "@removed": {
+ "reason": "changed"
+ },
+ "@id": "Employees(4)"
+ },
+ {
+ "@id": "Employees(5)"
+ },
+ {
+ "@id": "Employees(6)",
+ "LastName": "Smith"
+ },
+ {
+ "FirstName": "Suzanne",
+ "LastName": "Brown"
+ }
+ ]
}
Clients MAY associate an id with individual nested entities in the request by using the Core.ContentID
term defined in OData-VocCore. Services that respond with 200 OK
SHOULD annotate the entities in the response using the same Core.ContentID
value as specified in the request. Services SHOULD advertise support for deep updates, including support for returning the Core.ContentID
, through the Capabilities.DeepUpdateSupport
term, defined in OData-VocCap.
The response, if requested, is a collection payload containing the updated representation of each member identified by the request. If the update payload includes nested collections or nested delta collections, then they MUST be included in the response, as described in Update a Collection of Entities.
@@ -2074,8 +2075,8 @@Example 86: the function MostRecentOrder
can be bound to any URL that identifies a SampleModel.Customer
Function Name="MostRecentOrder" IsBound="true">
- <Parameter Name="customer" Type="SampleModel.Customer" />
- <ReturnType Type="SampleModel.Order" />
+ <Parameter Name="customer" Type="SampleModel.Customer" />
+ <ReturnType Type="SampleModel.Order" />
<Function> </
An efficient format that assumes client knowledge of metadata may omit actions and functions from the payload whose target URL can be computed via metadata following standard conventions defined in OData-URL.
+An efficient format that assumes client knowledge of metadata may omit actions and functions from the payload whose target URL can be computed via metadata following standard conventions defined in OData-URL.
Services can advertise that a function or action is not available for a particular instance by setting its value to null.
Example 92: the SampleEntities.MostRecentOrder
function is not available for customer ALFKI
{
- "@context": …,
- "CustomerID": "ALFKI",
- "CompanyName": "Alfreds Futterkiste",
- "#SampleEntities.MostRecentOrder": null,
- …
+"@context": …,
+ "CustomerID": "ALFKI",
+ "CompanyName": "Alfreds Futterkiste",
+ "#SampleEntities.MostRecentOrder": null,
+ …
}
Functions are operations exposed by an OData service that MUST return data and MUST have no observable side effects.
To invoke a function bound to a resource, the client issues a GET
request to a function URL. A function URL may be obtained from a previously returned entity representation or constructed by appending the namespace- or alias-qualified function name to a URL that identifies a resource whose type is the same as, or derived from, the type of the binding parameter of the function. The value for the binding parameter is the value of the resource identified by the URL prior to appending the function name, and additional parameter values are specified using inline parameter syntax. If the function URL is obtained from a previously returned entity representation, parameter aliases that are identical to the parameter name preceded by an at (@
) sign MUST be used. Clients MUST check if the obtained URL already contains a query part and appropriately precede the parameters either with an ampersand (&
) or a question mark (?
).
Services MAY additionally support invoking functions using the unqualified function name by defining one or more default namespaces through the Core.DefaultNamespace
term defined in OData-VocCore.
Services MAY additionally support invoking functions using the unqualified function name by defining one or more default namespaces through the Core.DefaultNamespace
term defined in OData-VocCore.
To request processing of the function only if the binding parameter value, an entity or collection of entities, is unmodified, the client includes the If-Match
header with the latest known ETag value for the entity or collection of entities. The ETag value for a collection as a whole is transported in the ETag
header of a collection response.
Functions can be used within $filter
or $orderby
system query options. Such functions can be bound to a resource, as described above, or called directly by specifying the namespace- (or alias-) qualified function name. Parameter values for functions within $filter
or $orderby
are specified according to the inline parameter syntax.
To invoke a function through a function import the client issues a GET
request to a URL identifying the function import and passing parameter values using inline parameter syntax. The canonical URL for a function import is the service root, followed by the name of the function import. Services MAY support omitting the parentheses when invoking a function import with no parameters, but for maximum interoperability MUST also support invoking the function import with empty parentheses.
Example 93: add a new item to the list of items of the shopping cart returned by the composable MyShoppingCart
function import
POST http://host/service/MyShoppingCart()/Items
-
+
…
If the function returns a value of type Edm.Stream
and no additional path segments follow the function invocation, the response to the GET
request follows the rules for requesting stream properties.
Parameter values passed to functions MUST be specified either as a URL literal (for primitive values) or as a JSON formatted OData object (for complex values, or collections of primitive or complex values). Entity typed values are passed as JSON formatted entities that MAY include a subset of the properties, or just the entity reference, as appropriate to the function.
+Parameter values passed to functions MUST be specified either as a URL literal (for primitive values) or as a JSON formatted OData object (for complex values, or collections of primitive or complex values). Entity typed values are passed as JSON formatted entities that MAY include a subset of the properties, or just the entity reference, as appropriate to the function.
If a collection-valued function has no result for a given parameter value combination, the response is the format-specific representation of an empty collection. If a single-valued function with a nullable return-type has no result, the service returns 204 No Content
.
If a single-valued function with a non-nullable return type has no result, the service returns 4xx
. For functions that return a single entity 404 Not Found
is the appropriate response code.
For a composable function the processing is stopped when the function result requires a 4xx
response, and continues otherwise.
Example 95: return all Customers whose City
property returns Western
when passed to the Sales.SalesRegion
function
GET http://host/service/Customers?
- $filter=Sales.SalesRegion(City=$it/City) eq 'Western'
+ $filter=Sales.SalesRegion(City=$it/City) eq 'Western'
A parameter alias can be used in place of an inline parameter value. The value for the alias is specified as a separate query option using the name of the parameter alias.
Actions are operations exposed by an OData service that MAY have side effects when invoked. Actions MAY return data but MUST NOT be further composed with additional path segments.
To invoke an action bound to a resource, the client issues a POST
request to an action URL. An action URL may be obtained from a previously returned entity representation or constructed by appending the namespace- or alias-qualified action name to a URL that identifies a resource whose type is the same as, or derives from, the type of the binding parameter of the action. The value for the binding parameter is the resource identified by the URL preceding the action name, and only the non-binding parameter values are passed in the request body according to the particular format.
Services MAY additionally support invoking actions using the unqualified action name by defining one or more default namespaces through the Core.DefaultNamespace
term defined in OData-VocCore.
Services MAY additionally support invoking actions using the unqualified action name by defining one or more default namespaces through the Core.DefaultNamespace
term defined in OData-VocCore.
To invoke an action through an action import, the client issues a POST
request to a URL identifying the action import. The canonical URL for an action import is the service root, followed by the name of the action import. When invoking an action through an action import all parameter values MUST be passed in the request body according to the particular format.
Non-binding parameters that are nullable or annotated with the term Core.OptionalParameter
defined in OData-VocCore MAY be omitted from the request body. If an omitted parameter is not annotated (and thus nullable), it MUST be interpreted as having the null
value. If it is annotated and the annotation specifies a DefaultValue
, the omitted parameter is interpreted as having that default value. If omitted and the annotation does not specify a default value, the service is free on how to interpret the omitted parameter. Note: a nullable non-binding parameter is equivalent to being annotated as optional with a default value of null
.
4.01 services MUST support invoking actions with no non-binding parameters and parameterless action imports both without a request body and with a request body representing no parameters, according to the particular format. Interoperable clients SHOULD always include a request body, even when invoking actions with no non-binding parameters and parameterless action imports.
@@ -2206,11 +2207,11 @@The body of a multipart batch request is made up of a series of individual requests and change sets, each represented as a distinct body part (i.e. preceded by a boundary delimiter line consisting of two dashes and the value of the boundary
parameter specified in the Content-Type
header, and the last body part followed by a closing boundary delimiter line consisting of two dashes, the boundary, and another two dashes).
A body part representing an individual request MUST include a Content-Type
header with value application/http
.
The contents of a body part representing a change set MUST itself be a multipart document (see RFC2046) with one body part for each operation in the change set. [E]{.MsoCommentReference}ach body part representing an operation in the change set MUST specify a Content-ID
header with a request identifier that is unique within the batch request.
The contents of a body part representing a change set MUST itself be a multipart document (see RFC2046) with one body part for each operation in the change set. Each body part representing an operation in the change set MUST specify a Content-ID
header with a request identifier that is unique within the batch request.
A Content-Transfer-Encoding
header with value binary
may be included for historic reasons although this header is not used by HTTP and only needed for transmission via E-Mail. Neither clients nor services should rely on this header being present.
Preambles and epilogues in the multipart batch request body, as defined in RFC2046, are valid but are assigned no meaning and thus MUST be ignored by processors of multipart batch requests.
The request URL of individual requests within a batch request or change set can use one of the following three formats:
@@ -2289,7 +2290,7 @@Example 101:
-GET https://host:1234/path/service/People(1) HTTP/1.1
+GET https://host:1234/path/service/People(1) HTTP/1.1
Host
headerThe service MUST process the individual requests and change sets within a multipart batch request in the order received. Processing stops on the first error unless the continue-on-error
preference is specified with an explicit or implicit value of true
.
Fielding, R., Ed., M. Nottingham, Ed., and J. Reschke, Ed., “HTTP Semantics”, RFC 9110, June 2022
https://www.rfc-editor.org/info/rfc9110.
ECMAScript 2023 Language Specification, 14th Edition, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
Time slices for the same temporal object are non-overlapping, so for any given point in time there is at most one slice whose time period contains that point in time.
Time slices for a temporal object need not cover the complete timeline. There can be points in time for which no time slice exists, indicating that the object’s values are not known to the service.
Time slices typically use closed-open semantics, following [SQL:2011]. This means the start is part of the period, the end is not part of the period, and for directly adjacent time slices the end of the earlier time slice is identical to the start of the next time slice. The period start must be less than the period end.
+Time slices typically use closed-open semantics, following SQL:2011. This means the start is part of the period, the end is not part of the period, and for directly adjacent time slices the end of the earlier time slice is identical to the start of the next time slice. The period start must be less than the period end.
Some software systems predating the availability of temporal databases and with data type date for the application-time period start and end use closed-closed semantics. Temporal services on top of these systems can either convert their period end boundaries on-the-fly by adding one day on the way out and subtracting one day on the way in, or alternatively express the used time slice semantics via annotations.
Keeping track of time is typically done by storing data together with the time period for which that data is deemed valid or effective, using separate periods for application time and system time, and the time periods are part of the logical key for “records”. See [SQL:2011] or [Kulkarni] on how this is done in the SQL standard.
+Keeping track of time is typically done by storing data together with the time period for which that data is deemed valid or effective, using separate periods for application time and system time, and the time periods are part of the logical key for “records”. See SQL:2011 or Kulkarni on how this is done in the SQL standard.
A consumer’s perspective on this data can be different: even if time is tracked internally, the period of time may or may not be visible in a consumer’s perspective, and even if visible the related properties are often not considered part of an entity’s identity. For example, an employee is still the same person even after switching to another department.
The goals of this extension are:
Example 6: Employees
entity set from example model api-1
annotated with temporal terms
"Employees": {
- "$Collection": true,
- "$Type": "OrgModel.Employee",
- "@Temporal.ApplicationTimeSupport": {
- "Timeline": {
- "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineSnapshot"
- },
- "UnitOfTime": {
- "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate"
- }
- }
+"$Collection": true,
+ "$Type": "OrgModel.Employee",
+ "@Temporal.ApplicationTimeSupport": {
+ "Timeline": {
+ "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineSnapshot"
+ },
+ "UnitOfTime": {
+ "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate"
+ }
+ }
},
Example 7: history
navigation property in entity set Employees
from example model api-2
annotated with temporal terms
"$Annotations": {
- "OrgModel.Default/Employees/history": {
- "@Temporal.ApplicationTimeSupport": {
- "Timeline": {
- "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineVisible",
- "TimeSliceStart": "From",
- "TimeSliceEnd": "To",
- "SupportedActions": [
- "Temporal.Update",
- "Temporal.Upsert",
- "Temporal.Delete"
- ]
- },
- "UnitOfTime": {
- "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate"
- }
- }
- }
+"OrgModel.Default/Employees/history": {
+ "@Temporal.ApplicationTimeSupport": {
+ "Timeline": {
+ "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.TimelineVisible",
+ "TimeSliceStart": "From",
+ "TimeSliceEnd": "To",
+ "SupportedActions": [
+ "Temporal.Update",
+ "Temporal.Upsert",
+ "Temporal.Delete"
+ ]
+ },
+ "UnitOfTime": {
+ "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.json#Temporal.UnitOfTimeDate"
+ }
+ }
+ }
}
Example 8: CostCenters
entity set containing time slices for multiple temporal objects, the temporal objects identified by combination of AreaID
and CostCenterID
"CostCenter": {
- "$Kind": "EntityType",
- "$Key": ["tsid"],
- "tsid": {},
- "AreaID": {},
- "CostCenterID": {},
- "ValidTo": { "$Type": "Edm.Date" },
- "ValidFrom": { "$Type": "Edm.Date" },
- "ProfitCenterID": { "$Nullable": true },
- "DepartmentID": { "$Nullable": true }
+"$Kind": "EntityType",
+ "$Key": ["tsid"],
+ "tsid": {},
+ "AreaID": {},
+ "CostCenterID": {},
+ "ValidTo": { "$Type": "Edm.Date" },
+ "ValidFrom": { "$Type": "Edm.Date" },
+ "ProfitCenterID": { "$Nullable": true },
+ "DepartmentID": { "$Nullable": true }
},
"Default": {
- "$Kind": "EntityContainer",
- "CostCenters": { "$Collection": true, "$Type": "this.CostCenter" }
+"$Kind": "EntityContainer",
+ "CostCenters": { "$Collection": true, "$Type": "this.CostCenter" }
},
"$Annotations": {
- "this.Default/CostCenters": {
- "@Temporal.ApplicationTimeSupport": {
- "UnitOfTime": {
- "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.UnitOfTimeDate",
- "ClosedClosedPeriods": true
- },
- "Timeline": {
- "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.TimelineVisible",
- "PeriodStart": "ValidFrom",
- "PeriodEnd": "ValidTo",
- "ObjectKey": ["AreaID", "CostCenterID"]
- },
- "SupportedActions": [
- "Temporal.Update",
- "Temporal.Upsert",
- "Temporal.Delete"
- ]
- }
- }
+"this.Default/CostCenters": {
+ "@Temporal.ApplicationTimeSupport": {
+ "UnitOfTime": {
+ "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.UnitOfTimeDate",
+ "ClosedClosedPeriods": true
+ },
+ "Timeline": {
+ "@odata.type": "https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Temporal.V1.xml#Temporal.TimelineVisible",
+ "PeriodStart": "ValidFrom",
+ "PeriodEnd": "ValidTo",
+ "ObjectKey": ["AreaID", "CostCenterID"]
+ },
+ "SupportedActions": [
+ "Temporal.Update",
+ "Temporal.Upsert",
+ "Temporal.Delete"
+ ]
+ }
+ }
}
GET /api-1/Employees('E314')
results in
{
- "@odata.context": "$metadata#Employees/$entity",
- "ID": "E314",
- "Name": "McDevitt",
- "Jobtitle": "Senior"
+"@odata.context": "$metadata#Employees/$entity",
+ "ID": "E314",
+ "Name": "McDevitt",
+ "Jobtitle": "Senior"
}
Expanding related entities in combination with $at
is straight-forward: the response consists of the time slices of related entities that are valid at the requested point in time. The period boundaries of the nested entities reflect the actual validity of the related entities and are independent of the period boundaries of the base entity.
GET /api-1/Employees('E314')?$at=2012-01-01&$expand=Department($at=2021-11-23)
results in
{
- "@odata.context": "$metadata#Employees/$entity",
- "ID": "E314",
- "Name": "McDevitt",
- "Jobtitle": "Junior",
- "Department": {
- "ID": "D08",
- "Name": "1st Level Support"
- }
+"@odata.context": "$metadata#Employees/$entity",
+ "ID": "E314",
+ "Name": "McDevitt",
+ "Jobtitle": "Junior",
+ "Department": {
+ "ID": "D08",
+ "Name": "1st Level Support"
+ }
}
$from
, $to
, and $toInclusive
Example 14: retrieve employee history over a period of application time
GET /api-2/Employees?$expand=history($select=Name,Jobtitle)
- &$from=2012-03-01&$to=2025-01-01
+ &$from=2012-03-01&$to=2025-01-01
results in one entity for each employee with time slices that overlap the specified application-time period:
{
- "@odata.context": "$metadata#Employees",
- "value": [
- {
- "ID": "E314",
- "history": [
- {
- "Name": "McDevitt",
- "Jobtitle": "Junior",
- "From": "2011-01-01",
- "To": "2013-10-01"
- },
- {
- "Name": "McDevitt",
- "Jobtitle": "Senior",
- "From": "2013-10-01",
- "To": "2014-01-01"
- },
- {
- "Name": "McDevitt",
- "Jobtitle": "Senior",
- "From": "2014-01-01",
- "To": "9999-12-31"
- }
- ]
- },
- {
- "ID": "E401",
- "history": [
- {
- "Name": "Gibson",
- "Jobtitle": "Expert",
- "From": "2012-03-01",
- "To": "9999-12-31"
- }
- ]
- }
- ]
+"@odata.context": "$metadata#Employees",
+ "value": [
+ {
+ "ID": "E314",
+ "history": [
+ {
+ "Name": "McDevitt",
+ "Jobtitle": "Junior",
+ "From": "2011-01-01",
+ "To": "2013-10-01"
+ },
+ {
+ "Name": "McDevitt",
+ "Jobtitle": "Senior",
+ "From": "2013-10-01",
+ "To": "2014-01-01"
+ },
+ {
+ "Name": "McDevitt",
+ "Jobtitle": "Senior",
+ "From": "2014-01-01",
+ "To": "9999-12-31"
+ }
+ ]
+ },
+ {
+ "ID": "E401",
+ "history": [
+ {
+ "Name": "Gibson",
+ "Jobtitle": "Expert",
+ "From": "2012-03-01",
+ "To": "9999-12-31"
+ }
+ ]
+ }
+ ]
}
The history for the first employee contains two time slices that do not differ in the represented properties, caused by a department change, and the department is not part of the representation.
The service could have combined these two time slices into one.
@@ -1601,97 +1601,97 @@Example 15: retrieve all employees that ever worked for department D15, with their full history, and the department’s data at the start of each employee history time slice
GET /api-2/Departments('D15')/Employees?
- $expand=history(
+ $expand=history(
@emp=$this;
- $expand=Department(
- $expand=history($at=@emp/From)
- )
- )
+ $expand=Department(
+ $expand=history($at=@emp/From)
+ )
+ )
has the following result with department names and budgets as of the beginning of each employee time slice:
{
- "@odata.context": "$metadata#Employees",
- "value": [
- {
- "ID": "E314",
- "history": [
- {
- "Name": "McDevitt",
- "Jobtitle": "Junior",
- "From": "2011-01-01",
- "To": "2013-10-01",
- "Department": {
- "ID": "D08",
- "history": [{
- "Name": "Support",
- "Budget": 1000,
- "From": "2010-01-01",
- "To": "2012-10-01"
- }]
- }
- },
- {
- "Name": "McDevitt",
- "Jobtitle": "Senior",
- "From": "2013-10-01",
- "To": "2014-01-01",
- "Department": {
- "ID": "D08",
- "history": [{
- "Name": "1st Level Support",
- "Budget": 1250,
- "From": "2012-06-01",
- "To": "2014-01-01"
- }]
- }
- },
- {
- "Name": "McDevitt",
- "Jobtitle": "Senior",
- "From": "2014-01-01",
- "To": "9999-12-31",
- "Department": {
- "ID": "D15",
- "history": [{
- "Name": "Services",
- "Budget": 1170,
- "From": "2011-01-01",
- "To": "9999-12-31"
- }]
- }
- }
- ]
- },
- {
- "ID": "E401",
- "history": [
- {
- "Name": "Norman",
- "Jobtitle": "Expert",
- "From": "2009-11-01",
- "To": "2012-03-01",
- "Department": {
- "ID": "D15",
- "history": []
- }
- },
- {
- "Name": "Gibson",
- "Jobtitle": "Expert",
- "From": "2012-03-01",
- "To": "9999-12-31",
- "Department": {
- "ID": "D15",
- "history": [{
- "Name": "Services",
- "Budget": 1170,
- "From": "2011-01-01",
- "To": "9999-12-31"
- }]
- }
- }
- ]
- }
- ]
+"@odata.context": "$metadata#Employees",
+ "value": [
+ {
+ "ID": "E314",
+ "history": [
+ {
+ "Name": "McDevitt",
+ "Jobtitle": "Junior",
+ "From": "2011-01-01",
+ "To": "2013-10-01",
+ "Department": {
+ "ID": "D08",
+ "history": [{
+ "Name": "Support",
+ "Budget": 1000,
+ "From": "2010-01-01",
+ "To": "2012-10-01"
+ }]
+ }
+ },
+ {
+ "Name": "McDevitt",
+ "Jobtitle": "Senior",
+ "From": "2013-10-01",
+ "To": "2014-01-01",
+ "Department": {
+ "ID": "D08",
+ "history": [{
+ "Name": "1st Level Support",
+ "Budget": 1250,
+ "From": "2012-06-01",
+ "To": "2014-01-01"
+ }]
+ }
+ },
+ {
+ "Name": "McDevitt",
+ "Jobtitle": "Senior",
+ "From": "2014-01-01",
+ "To": "9999-12-31",
+ "Department": {
+ "ID": "D15",
+ "history": [{
+ "Name": "Services",
+ "Budget": 1170,
+ "From": "2011-01-01",
+ "To": "9999-12-31"
+ }]
+ }
+ }
+ ]
+ },
+ {
+ "ID": "E401",
+ "history": [
+ {
+ "Name": "Norman",
+ "Jobtitle": "Expert",
+ "From": "2009-11-01",
+ "To": "2012-03-01",
+ "Department": {
+ "ID": "D15",
+ "history": []
+ }
+ },
+ {
+ "Name": "Gibson",
+ "Jobtitle": "Expert",
+ "From": "2012-03-01",
+ "To": "9999-12-31",
+ "Department": {
+ "ID": "D15",
+ "history": [{
+ "Name": "Services",
+ "Budget": 1170,
+ "From": "2011-01-01",
+ "To": "9999-12-31"
+ }]
+ }
+ }
+ ]
+ }
+ ]
}
Example 16: retrieve employee history over a period of application time and filter on job title
GET /api-2/Employees?$expand=history(
- $select=Name,Jobtitle;
- $from=2012-03-01&$to=2025-01-01;
- $filter=contains(Jobtitle,'e')
- )
+ $select=Name,Jobtitle;
+ $from=2012-03-01&$to=2025-01-01;
+ $filter=contains(Jobtitle,'e')
+ )
results in one entity for each employee with time slices that overlap the specified application-time period and satisfy the filter condition (one less than in example 14):
{
- "@odata.context": "$metadata#Employees",
- "value": [
- {
- "ID": "E314",
- "history": [
- {
- "Name": "McDevitt",
- "Jobtitle": "Senior",
- "From": "2013-10-01",
- "To": "2014-01-01"
- },
- {
- "Name": "McDevitt",
- "Jobtitle": "Senior",
- "From": "2014-01-01",
- "To": "9999-12-31"
- }
- ]
- },
- {
- "ID": "E401",
- "history": [
- {
- "Name": "Gibson",
- "Jobtitle": "Expert",
- "From": "2012-03-01",
- "To": "9999-12-31"
- }
- ]
- }
- ]
+"@odata.context": "$metadata#Employees",
+ "value": [
+ {
+ "ID": "E314",
+ "history": [
+ {
+ "Name": "McDevitt",
+ "Jobtitle": "Senior",
+ "From": "2013-10-01",
+ "To": "2014-01-01"
+ },
+ {
+ "Name": "McDevitt",
+ "Jobtitle": "Senior",
+ "From": "2014-01-01",
+ "To": "9999-12-31"
+ }
+ ]
+ },
+ {
+ "ID": "E401",
+ "history": [
+ {
+ "Name": "Gibson",
+ "Jobtitle": "Expert",
+ "From": "2012-03-01",
+ "To": "9999-12-31"
+ }
+ ]
+ }
+ ]
}
The lambda operators any()
and all()
are not influenced by temporal query options, they are interpreted for each time slice on the filtered collection, meaning “any related time slice satisfying the lambda expression” and “all related time slices satisfy the lambda expression”. The lambda expressions however can contain sub-expressions working on the period boundaries.
Example 17: filter employees on their name at any point in time
GET /api-2/Employees?$expand=history($select=Name,Jobtitle)
- &$from=2015-01-01
- &$filter=history/any(h:startswith(h/Name,'N'))
+ &$from=2015-01-01
+ &$filter=history/any(h:startswith(h/Name,'N'))
results in one employee whose name matches in the past, and the matching time slice is not in the requested time period
{
- "@odata.context": "$metadata#Employees",
- "value": [
- {
- "ID": "E401",
- "history": [
- {
- "Name": "Gibson",
- "Jobtitle": "Expert",
- "From": "2012-03-01",
- "To": "9999-12-31"
- }
- ]
- }
- ]
+"@odata.context": "$metadata#Employees",
+ "value": [
+ {
+ "ID": "E401",
+ "history": [
+ {
+ "Name": "Gibson",
+ "Jobtitle": "Expert",
+ "From": "2012-03-01",
+ "To": "9999-12-31"
+ }
+ ]
+ }
+ ]
}
Given the example departments data the operation will split the time slice starting at 2012-01-01 creating a new time slice starting at 2012-04-01 which is then updated with the desired budget. It will then update the time slice starting at 2012-06-01 with the desired budget, and finally it will split the time slice starting at 2014-01-01 creating a new time slice starting at 2014-07-01, then update the original with the desired budget, leaving the new time slice starting at 2014-07-01 untouched:
The service could have joined the third and fourth time slice because they do not significantly differ.
@@ -1952,17 +1952,17 @@api-1
(snapshot). Note that the period boundaries are not visible in api-1
and are provided as PeriodStart
and PeriodEnd
next to the Timeslice
data. The PeriodEnd
is omitted, meaning the end of application time.
POST /api-1/Employees/Temporal.Update
Content-Type: application/json
-
+
{
- "deltaTimeslices": [
- {
- "PeriodStart": "2021-10-01",
- "Timeslice": {
- "ID": "E401",
- "Jobtitle": "Ultimate Expert"
- }
- }
- ]
+"deltaTimeslices": [
+ {
+ "PeriodStart": "2021-10-01",
+ "Timeslice": {
+ "ID": "E401",
+ "Jobtitle": "Ultimate Expert"
+ }
+ }
+ ]
}
Given the example employee data the operation will split the time slice for employee E401
starting at 2012-03-01 creating a new time slice starting at 2021-10-01 which is then updated with the desired job title.
Given this example data (primary key in olive)
{
- "@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)",
- "value": [
- {
- "Timeslice": {
- "@odata.context": "#CostCenters/$entity",
- "tsid": "n",
- "AreaID": "51",
- "CostCenterID": "C1",
- "ValidTo": "1984-03-31",
- "ValidFrom": "1955-04-01",
- "ProfitCenterID": "P1",
- "DepartmentID": "D02"
- }
- },
- {
- "Timeslice": {
- "@odata.context": "#CostCenters/$entity",
- "tsid": "o",
- "AreaID": "51",
- "CostCenterID": "C1",
- "ValidTo": "2001-03-31",
- "ValidFrom": "1984-04-01",
- "ProfitCenterID": "P2",
- "DepartmentID": "D02"
- }
- },
- {
- "Timeslice": {
- "@odata.context": "#CostCenters/$entity",
- "tsid": "p",
- "AreaID": "51",
- "CostCenterID": "C1",
- "ValidTo": "9999-12-31",
- "ValidFrom": "2001-04-01",
- "ProfitCenterID": "P1",
- "DepartmentID": "D02"
- }
- },
- {
- "Timeslice": {
- "@odata.context": "#CostCenters/$entity",
- "tsid": "q",
- "AreaID": "51",
- "CostCenterID": "C2",
- "ValidTo": "9999-12-31",
- "ValidFrom": "2012-04-01",
- "ProfitCenterID": null,
- "DepartmentID": "D04"
- }
- }
- ]
+"@odata.context": "../$metadata#Collection(Temporal.TimesliceWithPeriod)",
+ "value": [
+ {
+ "Timeslice": {
+ "@odata.context": "#CostCenters/$entity",
+ "tsid": "n",
+ "AreaID": "51",
+ "CostCenterID": "C1",
+ "ValidTo": "1984-03-31",
+ "ValidFrom": "1955-04-01",
+ "ProfitCenterID": "P1",
+ "DepartmentID": "D02"
+ }
+ },
+ {
+ "Timeslice": {
+ "@odata.context": "#CostCenters/$entity",
+ "tsid": "o",
+ "AreaID": "51",
+ "CostCenterID": "C1",
+ "ValidTo": "2001-03-31",
+ "ValidFrom": "1984-04-01",
+ "ProfitCenterID": "P2",
+ "DepartmentID": "D02"
+ }
+ },
+ {
+ "Timeslice": {
+ "@odata.context": "#CostCenters/$entity",
+ "tsid": "p",
+ "AreaID": "51",
+ "CostCenterID": "C1",
+ "ValidTo": "9999-12-31",
+ "ValidFrom": "2001-04-01",
+ "ProfitCenterID": "P1",
+ "DepartmentID": "D02"
+ }
+ },
+ {
+ "Timeslice": {
+ "@odata.context": "#CostCenters/$entity",
+ "tsid": "q",
+ "AreaID": "51",
+ "CostCenterID": "C2",
+ "ValidTo": "9999-12-31",
+ "ValidFrom": "2012-04-01",
+ "ProfitCenterID": null,
+ "DepartmentID": "D04"
+ }
+ }
+ ]
}
Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017
https://www.rfc-editor.org/info/rfc8174.
Martin Fowler, “Temporal Patterns”, 16 February 2005
http://martinfowler.com/eaaDev/timeNarrative.html.
Krishna Kulkarni, “Temporal Features in SQL standard”, September 2012
https://dbs.uni-leipzig.de/file/Temporal%20features%20in%20SQL2011.pdf.
Richard T. Snodgrass, “Developing Time-Oriented Database Applications in SQL”, Morgan Kaufmann Publishers, Inc., San Francisco, July, 1999, ISBN 1-55860-436-7
http://www2.cs.arizona.edu/people/rts/tdbbook.pdf and http://www2.cs.arizona.edu/people/rts/pp30-31.pdf.
ISO/IEC 9075-2:2011 Information technology - Database languages - SQL - Part 2: Foundation (SQL/Foundation).
matchespattern
The matchespattern
function has the following signature:
Edm.Boolean matchespattern(Edm.String,Edm.String)
-The second parameter MUST evaluate to a string containing an [ECMAScript] (JavaScript) regular expression. The matchespattern
function returns true if the first parameter evaluates to a string matching that regular expression, using syntax and semantics of [ECMAScript] regular expressions, otherwise it returns false.
The second parameter MUST evaluate to a string containing an matchespattern
function returns true if the first parameter evaluates to a string matching that regular expression, using syntax and semantics of ECMAScript regular expressions, otherwise it returns false.
Example 81: all customers with a CompanyName
that match the (percent-encoded) regular expression ^A.*e$
http://host/service/Customers?$filter=matchespattern(CompanyName,'%5EA.*e$')
@@ -1946,7 +1946,7 @@ W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes. D. Peterson, S. Gao, C. M. Sperberg-McQueen, H. S. Thompson, P. V. Biron, A. Malhotra, Editors, W3C Recommendation, 5 April 2012.
http://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/. Latest version available at http://www.w3.org/TR/xmlschema11-2/.
ECMAScript 2023 Language Specification, 14th Edition, June 2023. Standard ECMA-262. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/.
A positive integer value specifying the maximum length of a binary, stream or string value. For binary or stream values this is the octet length of the binary data, for string values it is the character length (number of code points for Unicode).
If no maximum length is specified, clients SHOULD expect arbitrary length.
$MaxLength
$MaxLength
The value of $MaxLength
is a positive integer.
Note: OData-CSDL-XML defines a symbolic value max
that is only allowed in OData 4.0 responses. This symbolic value is not allowed in CDSL JSON documents at all. Services MAY instead specify the concrete maximum length supported for the type by the service or omit the member entirely.
For a temporal value (datetime-with-timezone-offset, duration, or time-of-day): the number of decimal places allowed in the seconds portion of the value; it MUST be a non-negative integer between zero and twelve.
Note: service authors SHOULD be aware that some clients are unable to support a precision greater than 28 for decimal values and 7 for temporal values. Client developers MUST be aware of the potential for data loss when round-tripping values of greater precision. Updating via PATCH
and exclusively specifying modified values will reduce the risk for unintended data loss.
Note: model elements with duration values and a granularity less than seconds (e.g. minutes, hours, days) can be annotated with the term Measures.DurationGranularity
, see OData-VocMeasures.
$Precision
$Precision
The value of $Precision
is a number.
Absence of $Precision
means unspecified precision both for decimal and temporal values.
An integer value means that the number of digits to the right of the decimal point may vary from zero to the value of the Scale
facet, and the number of digits to the left of the decimal point may vary from one to the value of the Precision
facet minus the value of the Scale
facet. If Precision
is equal to Scale
, a single zero MUST precede the decimal point.
The value of Scale
MUST be less than or equal to the value of Precision
.
Note: if the underlying data store allows negative scale, services may use a Precision
with the absolute value of the negative scale added to the actual number of significant decimal digits, and client-provided values may have to be rounded before being stored.
$Scale
$Scale
The value of $Scale
is a number or a string with one of the symbolic values floating
or variable
.
Services SHOULD use lower-case values; clients SHOULD accept values in a case-insensitive manner.
Absence of $Scale
means variable
.
$Scale
For a string-typed model element the Unicode
facet indicates whether the it might contain and accept string values with Unicode characters (code points) beyond the ASCII character set. The value false
indicates that the it will only contain and accept string values with characters limited to the ASCII character set.
If no value is specified, the Unicode
facet defaults to true
.
$Unicode
$Unicode
The value of $Unicode
is one of the Boolean literals true
or false
. Absence of the member means true
.
For a geometry- or geography-typed model element the SRID
facet identifies which spatial reference system is applied to its values.
The value of the SRID
facet MUST be a non-negative integer or the special value variable
. If no value is specified, the facet defaults to 0
for Geometry
types or 4326
for Geography
types.
The valid values of the SRID
facet and their meanings are as defined by the European Petroleum Survey Group EPSG.
$SRID
$SRID
The value of $SRID
is a string containing a number or the symbolic value variable
.
A CSDL JSON document consists of a single JSON object. This document object MUST contain the member $Version
.
The document object MAY contain the member $Reference
to reference other CSDL documents.
It also MAY contain members for schemas.
If the CSDL JSON document is the metadata document of an OData service, the document object MUST contain the member $EntityContainer
.
$Version
$Version
The value of $Version
is a string containing either 4.0
or 4.01
.
$EntityContainer
$EntityContainer
The value of $EntityContainer
is the namespace-qualified name of the entity container of that service. This is the only place where a model element MUST be referenced with its namespace-qualified name and use of the alias-qualified name is not allowed.
The Core.SchemaVersion
annotation, defined in OData-VocCore, MAY be used to indicate a particular version of the referenced document. If the Core.SchemaVersion
annotation is present, the $schemaversion
system query option, defined OData-Protocol, SHOULD be used when retrieving the referenced schema document.
$Reference
$Reference
The value of $Reference
is an object that contains one member per referenced CSDL document. The name of the pair is a URI for the referenced document. The URI MAY be relative to the document containing the $Reference
. The value of each member is a reference object.
The reference object MAY contain the members $Include
and $IncludeAnnotations
as well as annotations.
The alias MUST NOT be one of the reserved values Edm
, odata
, System
, or Transient
.
An alias is only valid within the document in which it is declared; a referencing document may define its own aliases for included schemas.
$Include
$Include
The value of $Include
is an array. Array items are objects that MUST contain the member $Namespace
and MAY contain the member $Alias
.
The item objects MAY contain annotations.
-$Namespace
$Namespace
The value of $Namespace
is a string containing the namespace of the included schema.
$Alias
$Alias
The value of $Alias
is a string containing the alias for the included schema.
The target namespace also provides consumers insight about what namespaces are present in the referenced document. If the consumer is not interested in that particular target namespace, the consumer can opt not to inspect the referenced document.
$IncludeAnnotations
$IncludeAnnotations
The value of $IncludeAnnotations
is an array. Array items are objects that MUST contain the member $TermNamespace
and MAY contain the members $Qualifier
and $TargetNamespace
.
$TermNamespace
$TermNamespace
The value of $TermNamespace
is a namespace.
$Qualifier
$Qualifier
The value of $Qualifier
is a simple identifier.
$TargetNamespace
$TargetNamespace
The value of $TargetNamespace
is a namespace.
Services SHOULD NOT have actions and functions with the same name, and MUST NOT have actions and functions with the same name bound to the same type.
Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case.
The namespace MUST NOT be one of the reserved values Edm
, odata
, System
, or Transient
.
A schema is represented as a member of the document object whose name is the schema namespace. Its value is an object that MAY contain the members $Alias
and $Annotations
.
The schema object MAY contain members representing entity types, complex types, enumeration types, type definitions, actions, functions, terms, and an entity container.
The schema object MAY also contain annotations that apply to the schema itself.
@@ -966,8 +966,8 @@If a schema specifies an alias, the alias MUST be used instead of the namespace within qualified names throughout the document to identify model elements of that schema. A mixed use of namespace-qualified names and alias-qualified names is not allowed.
Aliases are document-global, so all schemas defined within or included into a document MUST have different aliases, and aliases MUST differ from the namespaces of all schemas defined within or included into a document. Aliases defined by a schema can be used throughout the containing document and are not restricted to the schema that defines them.
The alias MUST NOT be one of the reserved values Edm
, odata
, System
, or Transient
.
$Alias
$Alias
The value of $Alias
is a string containing the alias for the schema.
$Alias
$Annotations
$Annotations
The value of $Annotations
is an object with one member per annotation target. The member name is a path identifying the annotation target, the member value is an object containing annotations for that target.
The entity type’s name is a simple identifier that MUST be unique within its schema.
An entity type can define two types of properties. A structural property is a named reference to a primitive, complex, or enumeration type, or a collection of primitive, complex, or enumeration types. A navigation property is a named reference to another entity type or collection of entity types.
All properties MUST have a unique name within an entity type. Properties MUST NOT have the same name as the declaring entity type. They MAY have the same name as one of the direct or indirect base types or derived types.
-An entity type is represented as a member of the schema object whose name is the unqualified name of the entity type and whose value is an object.
The entity type object MUST contain the member $Kind
with a string value of EntityType
.
It MAY contain the members $BaseType
, $Abstract
, $OpenType
, $HasStream
, and $Key
.
An entity type MUST NOT introduce an inheritance cycle by specifying a base type.
-$BaseType
$BaseType
The value of $BaseType
is the qualified name of the base type.
An abstract entity type MUST NOT inherit from a non-abstract entity type.
-$Abstract
$Abstract
The value of $Abstract
is one of the Boolean literals true
or false
. Absence of the member means false
.
An entity type MAY indicate that it is open and allows clients to add properties dynamically to instances of the type by specifying uniquely named property values in the payload used to insert or update an instance of the type.
An entity type derived from an open entity type MUST indicate that it is also open.
Note: structural and navigation properties MAY be returned by the service on instances of any structured type, whether or not the type is marked as open. Clients MUST always be prepared to deal with additional properties on instances of any structured type, see OData-Protocol.
-$OpenType
$OpenType
The value of $OpenType
is one of the Boolean literals true
or false
. Absence of the member means false
.
An entity type that does not specify a base type MAY indicate that it is a media entity type. Media entities are entities that represent a media stream, such as a photo. Use a media entity if the out-of-band stream is the main topic of interest and the media entity is just additional structured information attached to the stream. Use a normal entity with one or more properties of type Edm.Stream
if the structured data of the entity is the main topic of interest and the stream data is just additional information attached to the structured data. For more information on media entities see OData-Protocol.
An entity type derived from a media entity type MUST indicate that it is also a media entity type.
Media entity types MAY specify a list of acceptable media types using an annotation with term Core.AcceptableMediaTypes
, see OData-VocCore.
$HasStream
$HasStream
The value of $HasStream
is one of the Boolean literals true
or false
. Absence of the member means false
.
If the key property is a property of a complex property (recursively) or of a directly related entity type, the key MUST specify an alias for that property that MUST be a simple identifier and MUST be unique within the set of aliases, structural and navigation properties of the declaring entity type and any of its base types.
An alias MUST NOT be defined if the key property is a primitive property of the entity type itself.
For key properties that are a property of a complex or navigation property, the alias MUST be used in the key predicate of URLs instead of the path to the property because the required percent-encoding of the forward slash separating segments of the path to the property would make URL construction and parsing rather complicated. The alias MUST NOT be used in the query part of URLs, where paths to properties don’t require special encoding and are a standard constituent of expressions anyway.
-$Key
$Key
The value of $Key
is an array with one item per key property.
Key properties without a key alias are represented as strings containing the property name.
Key properties with a key alias are represented as objects with one member whose name is the key alias and whose value is a string containing the path to the property.
@@ -1194,8 +1194,8 @@The property’s name MUST be a simple identifier. It is used when referencing, serializing or deserializing the property. It MUST be unique within the set of structural and navigation properties of the declaring structured type, and MUST NOT match the name of any navigation property in any of its base types. If a structural property with the same name is defined in any of this type’s base types, then the property’s type MUST be a type derived from the type specified for the property of the base type and constrains this property to be of the specified subtype for instances of this structured type. The name MUST NOT match the name of any structural or navigation property of any of this type’s base types for OData 4.0 responses.
Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case.
-Structural properties are represented as members of the object representing a structured type. The member name is the property name, the member value is an object.
The property object MAY contain the member $Kind
with a string value of Property
. This member SHOULD be omitted to reduce document size.
It MAY contain the members $Type
, $Collection
, $Nullable
, $MaxLength
, $Unicode
, $Precision
, $Scale
, $SRID
, and $DefaultValue
.
The property’s type MUST be a primitive type, complex type, or enumeration type in scope, or a collection of one of these types.
A collection-valued property MAY be annotated with the Core.Ordered
term, defined in OData-VocCore, to specify that it supports a stable ordering.
A collection-valued property MAY be annotated with the Core.PositionalInsert
term, defined in OData-VocCore, to specify that it supports inserting items into a specific ordinal position.
$Type
and $Collection
$Type
and $Collection
For single-valued properties the value of $Type
is the qualified name of the property’s type.
For collection-valued properties the value of $Type
is the qualified name of the property’s item type, and the member $Collection
MUST be present with the literal value true
.
Absence of the $Type
member means the type is Edm.String
. This member SHOULD be omitted for string properties to reduce document size.
$Type
and 7.2 Nullable
A Boolean value specifying whether the property can have the value null
.
$Nullable
$Nullable
The value of $Nullable
is one of the Boolean literals true
or false
. Absence of the member means false
.
For single-valued properties the value true
means that the property allows the null
value.
For collection-valued properties the value will always be a collection that MAY be empty. In this case $Nullable
applies to items of the collection and specifies whether the collection MAY contain null
values.
$Nullable
A primitive- or enumeration-typed property MAY define a default value that is used if the property is not explicitly represented in an annotation or the body of a request or response.
If no value is specified, the client SHOULD NOT assume a default value.
-$DefaultValue
$DefaultValue
The value of $DefaultValue
is the type-specific JSON representation of the default value of the property, see OData-JSON. For properties of type Edm.Decimal
and Edm.Int64
the representation depends on the media type parameter IEEE754Compatible
.
Names are case-sensitive, but service authors SHOULD NOT choose names that differ only in case.
-