OData @ SAP - Documents

Annotation Cheat-Sheet for CAP CDS

How to construct an annotation from a term definition, or re-engineer a term definition from an annotation example?

Here's how.

Vocabularies

CAP CDS has the standard OASIS and SAP vocabularies built-in, their terms can be used without needing to reference the vocabulary, as long as the standard qualifiers are used, e.g. @Core for the OASIS Core vocabulary, or @Common for the SAP Common vocabulary.

Primitive Terms

If the term has a primitive type

<Term Name="StringTerm" Type="Edm.String" />

A constant annotation value can be provided as a corresponding JSON value.

@Vocab.StringTerm: 'annotation value'

See Constant Annotation Values for a list of all primitiv types and example values for them.

A dynamic annotation value can be provided for the same term using a CDS path expression that could be used in a SELECT clause.

@Vocab.StringTerm: Some.StringProperty

The property referenced via the value path expression, here Some.StringProperty needs to have the same type as the term. A value path expression can always be used instead of a constant value, also in the more complicated cases below.

Collections

If the term has a collection type

<Term Name="CollectionTerm" Type="Collection(Edm.Decimal)" />

the annotation value is provided as an array

@Vocab.CollectionTerm: [ 2.78, 3.14 ]

Structures

If the term has a structured type

<Term Name="StructuredTerm" Type="Vocab.Complex" />

<ComplexType Name="Complex">
  <Property Name="IntegerField" Type="Edm.Int32" />
</ComplexType>

the annotation value is provided as an object

@Vocab.StructuredTerm: {
  IntegerField: 42
}

Constant annotation values for primitive properties are provided in the same way as for primitive terms.

Collection of Structures

Terms can also be typed as a collection of a structured type.

<Term Name="StructuredCollectionTerm" Type="Collection(Vocab.AnotherComplex)" />

<ComplexType Name="AnotherComplex">
  <Property Name="DateField" Type="Edm.Date" />
  <Property Name="TimeField" Type="Edm.TimeOfDay" DefaultValue="00:00:00" />
</ComplexType>

The annotation value is provided as a collection of objects.

@Vocab.StructuredCollectionTerm: [
  {
    DateField: '2020-06-30',
    TimeField: '16:55:03'
  },
  {
    DateField: '2020-07-01'
  },
  {
    TimeField: '23:59:59'
  }
]

Properties that are nullable or have a default value can be omitted.

Nested Structures and Collections

Properties of a structured type can themselves be structured or collections.

<Term Name="NestedTerm" Type="Collection(Vocab.YetAnotherComplex)" />

<ComplexType Name="YetAnotherComplex">
  <Property Name="StructuredField" Type="Vocab.Complex" />
  <Property Name="CollectionField" Type="Collection(Vocab.AnotherComplex)" />
</ComplexType>

The property value is provided as an object or array.

@Vocab.NestedTerm: {
  StructuredField: {
    IntegerField: 42
  },
  CollectionField: [
    {
      DateField: '2020-06-30',
      TimeField: '16:55:03'
    }
  ]
}

Constant Annotation Values

The name of the attribute to provide a constant annotation value depends on the type of the term or term property.

Type of Term or Term Property Example Value
Edm.Binary 'T0RhdGE'
Edm.Boolean true
Edm.Date '2000-01-01'
Edm.DateTimeOffset '2000-01-01T16:00:00.000Z'
Edm.Decimal '3.14'
Edm.Duration 'P7D'
Enumeration Type #Red
Edm.Double or Edm.Single 3.14
Edm.Guid '21EC2020-3AEA-1069-A2DD-08002B30309D'
Edm.Int16, Edm.Int32, Edm.64, Edm.Byte, Edm.SByte 42
Edm.Int64 '42'
Edm.String 'annotation value'
Edm.TimeOfDay '21:45:00'
Edm.AnnotationPath 'Product/Supplier/@UI.LineItem'
Edm.NavigationPropertyPath Supplier
Edm.PropertyPath Details.ChangedAt