Vocabulary-Based Annotations
Maybe you’ve read the announcement that SAP NetWeaver Gateway SP7 is out and noted the last section about OData Vocabularies. This actually is the first feature of OData Version 4.0 to be implemented in SAP Netweaver Gateway!
Annotations are a powerful way of extending OData services. By annotating a service you add information that tells clients how to interpret the service and its data. This additional information can be purely static and descriptive, or it can be dynamic, i.e. a “formula” that allows clients to compute new data from the data provided by the service. And it can be provided by the service designer and embedded in the service’s metadata, or it can be provided by someone else as a separate web resource that references the annotated service.
In its simplest form you just tag parts of a service to tell clients how to interpret a piece of data. For example the OData Core vocabulary defines a term IsLanguageDependent. Tagging a string-valued property with this term tells clients that the value they receive may depend on the Content-Language of the response they got.
A more business-related use case is marking a numeric property as a monetary amount and linking the amount to its currency.
With OData 2.0 we had to invent SAP-specific annotations to express business semantics. A typical example of an annotated metadata document would look like this:
<Property Name=“OrderedQuantity” Type=“Edm.Int16” sap:unit=“OrderedUnit” /><Property Name=“OrderedUnit” Type=“Edm.String” sap:semantics=“unit-of-measure” /><Property Name=“Price” Type=“Edm.Decimal” Scale=“3”
sap:unit=“Currency” sap:precision=“DisplayScale” />
<Property Name=“DisplayScale” Type=“Edm.Byte” />
<Property Name=“Currency” Type=“Edm.String” MaxLength=“3”
sap:semantics=“currency-code” sap:text=“CurrencyText” />
<Property Name=“CurrencyText” Type=“Edm.String” />
The drawback of using custom annotations was that non-SAP client libraries at best gracefully ignore these SAP annotations, but to consume these annotations we had to provide SAP-specific libraries or library extensions, reducing some of the benefit we get from using a standardized protocol.
With OData 4.0 we can express semantic meta-information in a standardized way, and all fully compliant OData 4.0 client libraries will know how to parse these annotations and pass them on to the consuming applications. In OData 4.0 the same example will look like this:
<Property Name=“OrderedQuantity” Type=“Edm.Int16”>
<Annotation Term=“Measures.Unit” Path=“OrderedUnit” />
</Property>
<Property Name=“OrderedUnit” Type=“Edm.String” />
<Property Name=“Price” Type=“Edm.Decimal” Scale=“variable”>
<Annotation Term=“Measures.ISOCurrency” Path=“Currency” />
<Annotation Term=“Measures.Scale” Path=“DisplayScale” />
</Property>
<Property Name=“DisplayScale” Type=“Edm.Byte” />
<Property Name=“Currency” Type=“Edm.String” MaxLength=“3”>
<Annotation Term=“SAP.Text” Path=“CurrencyText” />
</Property>
<Property Name=“CurrencyText” Type=“Edm.String”>
<Annotation Term=“Core.IsLanguageDependent” />
</Property>
All annotations are expressed as <Annotation> elements that name the term that is applied to a model element as well as the value for this term. Here the value is described by the Path attribute, meaning “follow this path in the current entity to find the value for the term”, i.e. the consumer now knows that the ISO currency for the amount in the Price property can be found in the Currency property next to the Price property, etc.
But it does not end here: OData 4.0 allows describing the terms themselves in a machine-readable way, including their type and their applicability. This makes it possible to build generic tools that allow annotating any service with any vocabulary.
OData 4.0 defines three standard vocabularies: Core, Capabilities, and Measures. The example above uses three terms from the Measures vocabulary, one term from the Core vocabulary, and one SAP-specific term for a concept not present in the three standard vocabularies. The first important fact is that the annotations look the same for standardized terms and for custom terms. The second important fact is that the definitions of the standard terms and the custom terms also use the same language constructs.
The standard term for the ISO currency of a monetary amount defined in the Measures vocabulary is
<Term Name=“ISOCurrency” Type=“Edm.String” AppliesTo=“Property”>
<Annotation Term=“Core.Description”
String=“The currency for this monetary amount as an ISO 4217 currency code” /></Term>
The SAP-specific term for the human-readable text attached to a code value is defined as
<Term Name=“Text” Type=“Edm.String” AppliesTo=“Property”>
<Annotation Term=“Core.Description”
String=“A descriptive text for the value of the annotated property.
Value MUST be a dynamic expression when used as metadata annotation.” />
</Term>
Both term definitions have the same structure: the name of the term, its data type, using the OData type system, and optionally a white-space separated list of CSDL element names the term can be applied to.
And of course term definitions themselves can be annotated, typically with terms from the Core vocabulary. This vocabulary contains all terms that the OASIS OData Technical Committee deemed essential, both for writing vocabularies as well as for annotating typical OData services.
In a future document we’ll describe in detail how the SAP Annotations for OData Version 2.0 can be translated into OData 4.0 vocabulary-based annotations.
Have fun!
–Ralf
Addendum: in the meantime a lot has happened around annotations, most prominently Fiori Elements (fka Smart Templates), a way to quickly and easily build Fiori apps based on annotated OData services. In addition to the OData standard vocabularies
- Core – Core terms needed to write vocabularies
- Capabilities – Terms describing capabilities of a service
- Measures – Terms describing monetary amounts and measured quantities
- Validation – Terms describing validation rules
SAP has developed three additional vocabularies for describing data semantics and its abstract UI representation.
- SAP Common – centered on data semantics
- SAP Communication – centered on communication-relevant information
- SAP UI – centered on presenting data in user interfaces
No surprise that these vocabularies are at the heart of the Fiori Elements approach.
Hello Ralf,
It is my understanding that SAPUI5 can only handle oData services up to version 3.0 (maxDataVersion). Do you have any idea when it will be possible to consume these oData 4.0 annotation based services by SAPUI5 ?
Regards,
Bert
Hello Bert,
the UI5 core team is working on implementing annotations as part of the central data binding.
It's not yet in the nightly builds, but we are actively working on it.
Best regards,
Jens
Hello Jens,
Thanks for the update. Can't wait. OData 4.0 vocabulary-based annotations is going to be of greate use.
Regards,
Bert
Hi Ralf,
I enjoyed reading your article. It explains concept and implementation in a concise and readable way with examples and personal insight.
Thanks!
Hongying
Hi, Thanks for the post.
I have a question regarding the UI annotations from o-data and other sources.
Regarding the other SAP.UI and SAP.common “complimentary annotations”. I see these under the <Annotations> tag in the $metadata. But in any FIORI launchpad application, I see annotations are also supplied from
(i) – CATALOG SERVICE Url’s -> URLs are something like this
“*/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName=’SOME_NAME’,Version=’0001′,SAP__Origin=’LOCAL’)/$value”;”
ii) – annotations.xml -> application specific annotations provided by javascript app developer.
SAP UI5 somehow merges all the annotations from these resources and produce the UI.
I am interested to know how is this done? Algorithm? Is there any documentation on this topic i.e. on these UI <Annotations>, their sources and merging?
I have to understand this logic and extract this final set of annotations in JAVA and I am looking for some library (o-lingo doesn’t understand <Annotations> and does not talk with other sources of annotations) – I am exploring XScript and other xml parsers but I would really help to understand the algorithm that javascript uses to merge and understand these annotations.
Thanks,
Vivek