Skip to content

Commit 955b71f

Browse files
committed
odata-dd reorg vocabularies and annotations
1 parent cecfc57 commit 955b71f

2 files changed

Lines changed: 210 additions & 0 deletions

File tree

231 KB
Loading
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
---
2+
parser: v2
3+
author_name: DJ Adams
4+
author_profile: https://github.com/qmacro
5+
auto_validation: false
6+
primary_tag: software-product>sap-business-technology-platform
7+
tags: [ software-product>sap-business-technology-platform, topic>cloud, programming-tool>odata, tutorial>beginner ]
8+
time: 20
9+
---
10+
11+
# Understand how vocabularies are used in OData metadata documents
12+
13+
<!-- description --> Metadata can be extended, using content organized into vocabularies.
14+
15+
## You will learn
16+
17+
- How annotations are organized into vocabularies
18+
- How they're included within an OData metadata document
19+
20+
## Intro
21+
22+
The members of the OData Technical Committee have worked hard on OData as a robust, well-defined and extensible standard. In this tutorial we'll look at a key extensibility mechanism in the form of vocabularies, and how they're used to organize annotations.
23+
24+
---
25+
26+
### Examine the rest of the entity model wrapper
27+
28+
In the previous [Metadata](https://developers.sap.com/tutorials/odata-dd-4-metadata.html) tutorial we saw how the schema was presented within a context. That context is called the [entity model wrapper](https://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part3-csdl/odata-v4.0-errata03-os-part3-csdl-complete.html#_Toc453752500). We left the examination of part of that wrapper - the references to vocabularies - to this tutorial. Let's start by digging into those now.
29+
30+
Here's what the relevant section of the wrapper in [the Northbreeze OData service's metadata document](https://odd.cfapps.eu10.hana.ondemand.com/northbreeze/$metadata) looks like:
31+
32+
```xml
33+
<?xml version="1.0" encoding="utf-8"?>
34+
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
35+
<edmx:Reference
36+
Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml">
37+
<edmx:Include Alias="Capabilities" Namespace="Org.OData.Capabilities.V1"/>
38+
</edmx:Reference>
39+
<edmx:Reference
40+
Uri="https://sap.github.io/odata-vocabularies/vocabularies/Common.xml">
41+
<edmx:Include Alias="Common" Namespace="com.sap.vocabularies.Common.v1"/>
42+
</edmx:Reference>
43+
<edmx:Reference
44+
Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
45+
<edmx:Include Alias="Core" Namespace="Org.OData.Core.V1"/>
46+
</edmx:Reference>
47+
...
48+
</edmx:Edmx>
49+
```
50+
51+
What are these references? Well, section [3.3 Element edmx:Reference](https://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part3-csdl/odata-v4.0-errata03-os-part3-csdl-complete.html#_Toc453752504) of the CSDL standards document is helpful here (as well as section [3.1 Element edmx:Edmx](https://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part3-csdl/odata-v4.0-errata03-os-part3-csdl-complete.html#_Toc453752504) telling us that there can be zero or more of them within an `<edmx:Edmx>` element).
52+
53+
Basically, `edmx:Reference` elements point to external CSDL documents, specific content from which (indicated by the `edmx:Include` elements within) is then added to the overall scope of the referring (OData metadata) document.
54+
55+
Think of it like an "include" or "import" as found in various programming languages; these references might look like this in pseudo-JavaScript, for example:
56+
57+
```javascript
58+
import { "Org.OData.Capabilities.V1" as "Capabilities" } from "https://oasis-tcs.github.io/.../Org.OData.Capabilities.V1.xml";
59+
import { "com.sap.vocabularies.Common.v1" as "Common" } from "https://sap.github.io/.../Common.xml";
60+
import { "Org.OData.Core.V1" as "Core" } from "https://oasis-tcs.github.io/.../Org.OData.Core.V1.xml";
61+
```
62+
63+
### Meet the OData vocabularies
64+
65+
Note that each of the referenced external documents in our OData metadata document are resources in GitHub repositories:
66+
67+
- two belonging to OASIS in <https://oasis-tcs.github.io/odata-vocabularies/>
68+
- one belonging to SAP in <https://sap.github.io/odata-vocabularies/>
69+
70+
Taking the first of the three `<edmx:Reference>` elements here:
71+
72+
```xml
73+
<edmx:Reference
74+
Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml">
75+
<edmx:Include Alias="Capabilities" Namespace="Org.OData.Capabilities.V1"/>
76+
</edmx:Reference>
77+
```
78+
79+
we see that:
80+
81+
- the reference points to an [XML representation](https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml) of a CSDL document "Org.OData.Capabilities.V1"
82+
- moving one level up from that CSDL document resource's location, there is a [vocabularies overview page](https://oasis-tcs.github.io/odata-vocabularies/vocabularies/) listing each of the OASIS Technical Committee vocabularies, including this "Capabilities" one.
83+
- for each of these vocabulary resources there are HTML, XML and JSON representations
84+
- the HTML representation is especially useful for us as it describes the vocabulary's purpose in general, and gives details for each of the terms and types contained within it
85+
86+
![OASIS OData TC - Vocabularies](oasis-vocabularies-toc.png)
87+
88+
If we look specifically at the [XML source](https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml) representation of the "Capabilities" vocabulary in CSDL form, we see this:
89+
90+
```xml
91+
<?xml version="1.0" encoding="utf-8"?>
92+
...
93+
94+
Abstract:
95+
This document contains terms describing capabilities of an OData service.
96+
97+
-->
98+
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
99+
<edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Authorization.V1.xml">
100+
<edmx:Include Alias="Authorization" Namespace="Org.OData.Authorization.V1" />
101+
</edmx:Reference>
102+
<edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml">
103+
<edmx:Include Alias="Core" Namespace="Org.OData.Core.V1" />
104+
</edmx:Reference>
105+
<edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Validation.V1.xml">
106+
<edmx:Include Alias="Validation" Namespace="Org.OData.Validation.V1" />
107+
</edmx:Reference>
108+
<edmx:DataServices>
109+
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Org.OData.Capabilities.V1" Alias="Capabilities">
110+
...
111+
</Schema>
112+
</edmx:DataServices>
113+
</edmx:Edmx>
114+
```
115+
116+
It's another EDMX document! There is definitely a certain beauty to the OData specifications that is special.
117+
118+
Anyway, there are two thing of note here:
119+
120+
- this document _also_ has references to vocabularies
121+
- there is a single `<Schema>` element, with the OData namespace "Org.Data.Capabilities.V1"
122+
123+
And that specific schema is exactly the one that's referenced in the `<edmx:Include>` element within the `<edmx:Reference>` element:
124+
125+
```xml
126+
<edmx:Include Alias="Capabilities" Namespace="Org.OData.Capabilities.V1"/>
127+
```
128+
129+
It just so happens that in this referenced CSDL document, there _is_ only one schema, but there could be more.
130+
131+
So an `<edmx:Include>` element forms an important part of the `<edmx:Reference>`.
132+
133+
> Indeed, [section 3.3 Element edmx:Reference](https://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part3-csdl/odata-v4.0-errata03-os-part3-csdl-complete.html#_Toc453752504) states that at least one `<edmx:Include>` or `<edmx:IncludeAnnotation>` is mandatory.
134+
135+
The `<edmx:Include>` element serves to identify a particular schema to be included, from the referenced vocabulary. It also does one more thing here - it specifies a short name, in the form of a value for an `Alias` attribute, which can be used to refer to that imported vocabulary schema. Just like the `as` aliasing in our imaginary JavaScript equivalent example earlier. So instead of the full name "Org.OData.Capabilities.V1" being needed to prefix vocabulary terms, the short form "Capabilities" can be used, as we'll see in subsequent steps.
136+
137+
### Take a first look at the annotations
138+
139+
Now we understand how vocabulary resources are referenced to be included into an OData metadata document, let's now take a first look at what annotations are used in this particular OData metadata document, and how.
140+
141+
To set the scene, if we take brief look at the CSDL specification, we learn that:
142+
143+
- "Vocabulary annotations can be specified as a child of the model element being annotated or as a child of an `edm:Annotations` element that targets the model element." (from [section 4.6 Annotations](https://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part3-csdl/odata-v4.0-errata03-os-part3-csdl-complete.html#_Toc453752519))
144+
- "An annotation applies a term to a model element and defines how to calculate a value for the applied term." (from [section 14 Vocabulary and Annotation](https://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part3-csdl/odata-v4.0-errata03-os-part3-csdl-complete.html#_Vocabulary_and_Annotation))
145+
146+
Additionally:
147+
148+
- "A service SHOULD NOT require a client to interpret annotations. Clients SHOULD ignore unknown terms and silently treat unexpected or invalid values (including invalid type, invalid literal expression, etc.) as an unknown value for the term." ( also from [section 14 Vocabulary and Annotation](https://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part3-csdl/odata-v4.0-errata03-os-part3-csdl-complete.html#_Vocabulary_and_Annotation))
149+
150+
With the information from the first two points here, we can see in our OData metadata document that both approaches to annotation are used.
151+
152+
First, we see the "annotation as child element" approach where the annotation "Core.Links" is applied directly to the `<Schema>` element via the `<Annotation>` element which appears a direct child of `<Schema>`:
153+
154+
```xml
155+
<Schema Namespace="Main" xmlns="http://docs.oasis-open.org/odata/ns/edm">
156+
<Annotation Term="Core.Links">
157+
<Collection>
158+
<Record>
159+
<PropertyValue Property="rel" String="author"/>
160+
<PropertyValue Property="href" String="https://cap.cloud.sap"/>
161+
</Record>
162+
</Collection>
163+
</Annotation>
164+
...
165+
</Schema>
166+
```
167+
168+
Further on in the metadata document we see an example of the other approach, where `<Annotation>` elements appear as direct children of a containing `<Annotations>` element, and the schema elements to which the annotations are applied are specified in `Target` attributes):
169+
170+
> Again, as explained in the previous [Metadata](https://developers.sap.com/tutorials/odata-dd-4-metadata.html) tutorial, in the "Get acquainted with the schema element" step, we'll leave out the XML namespace prefix `edm` her when writing elements that belong to that namespace.
171+
172+
173+
```xml
174+
<Schema Namespace="Main" xmlns="http://docs.oasis-open.org/odata/ns/edm">
175+
...
176+
<EntityContainer Name="EntityContainer">
177+
<EntitySet Name="Categories" EntityType="Main.Categories">
178+
<NavigationPropertyBinding Path="Products" Target="Products"/>
179+
</EntitySet>
180+
</EntityContainer>
181+
...
182+
<Annotations Target="Main.EntityContainer/Categories">
183+
<Annotation Term="Capabilities.DeleteRestrictions">
184+
<Record Type="Capabilities.DeleteRestrictionsType">
185+
<PropertyValue Property="Deletable" Bool="false"/>
186+
</Record>
187+
</Annotation>
188+
<Annotation Term="Capabilities.InsertRestrictions">
189+
<Record Type="Capabilities.InsertRestrictionsType">
190+
<PropertyValue Property="Insertable" Bool="false"/>
191+
</Record>
192+
</Annotation>
193+
<Annotation Term="Capabilities.UpdateRestrictions">
194+
<Record Type="Capabilities.UpdateRestrictionsType">
195+
<PropertyValue Property="Updatable" Bool="false"/>
196+
</Record>
197+
</Annotation>
198+
</Annotations>
199+
</Schema>
200+
```
201+
202+
Here, three different annotations terms:
203+
204+
- Capabilities.DeleteRestrictions
205+
- Capabilities.InsertRestrictions
206+
- Capabilities.UpdateRestrictions
207+
208+
are being applied via `Target="Main.EntityContainer/Categories"` to the "Categories" entityset in the entity container named "EntityContainer" in the "Main" OData namespace.
209+
210+
In the next tutorial we'll dig in to the detail of the annotations used in this OData metadata document.

0 commit comments

Comments
 (0)