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 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 Name=“DisplayScale” Type=“Edm.Byte” />
<Property Name=“Currency” Type=“Edm.String” MaxLength=“3”>
<Annotation Term=“SAP.Text” Path=“CurrencyText” />
<Property Name=“CurrencyText” Type=“Edm.String”>
<Annotation Term=“Core.IsLanguageDependent” />
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”>
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”>
String=“A descriptive text for the value of the annotated property.
Value MUST be a dynamic expression when used as metadata annotation.” />
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.
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 Core, Capabilities, and Measures vocabularies that are part of the OData standard 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.