Skip to main content
Version: AMF v5.x.x

Writing, Applying and Reading Semantic Extensions

What you'll learn

  • What a Semantic Extension is
  • Writing extensions and applying them in an API spec.
  • Processing Semantic Extensions in your code.
  • Reading an extension from the Object Oriented interface

What a Semantic Extension is

"Semantic Extensions" is a mechanism to extend the semantic domain of an API specification like RAML or OpenApi.

We use AML to define mappings that will describe the AST structure used to parse the nodes that extend the domain of the source specification. Also, it allows map the AST structure to semantic terms.

We identify such nodes or extension points by using annotations (also called spec extensions).

Writing a Semantic Extension

To write a semantic extension we need to:

  • Create an AML Dialect document
  • Write an "AnnotationMapping" node under the "annotationMappings" key. This describes the structure that we expect the value of the semantic-extension to have.
  • Declare an extension under the "extensions" node and link it to the AnnotationMapping we wrote.
#%Dialect 1.0
dialect: Repository object extensions
version: 1.0

external:
apiContract: "http://a.ml/vocabularies/apiContract#"

documents:
root:
declares: {}

annotationMappings:
DeprecationMapping:
domain: apiContract.EndPoint
propertyTerm: apiContract.deprecated
range: Deprecation

nodeMappings:
Deprecation:
mapping:
replaceFor:
range: string
mandatory: true
message:
range: string
mandatory: true

extensions:
deprecated: DeprecationMapping

Examining the "DeprecationMapping" annotation

AnnotationMappings behave like PropertyMappings except that declaring "mapKey" and "mapValue" is not allowed.

The "DeprecationMapping" AnnotationMapping has 3 fields:

  • domain: instructs the AMFParser the models that may contain "semantic-extensions". This node's value should match a value of the models "@type" array. To see the possible AMF models to extend see: AMFs API Contract Model documentation.
  • propertyTerm: uri used to semantically describe the parsed extension model. This value will be used in the model to access the extension value. This access is described in the example.
  • range: desired structure of the semantic-extension's value. This can be a scalar value (string, integer, etc.) or a NodeMapping.

Examining the "deprecated" extension

Declarations under the "extensions" node expose an AnnotationMapping under a specific name, in this case "deprecated". An API Spec author or Dialect will be able to use the semantic-extension under the "deprecated" name.

Applying a Semantic Extension in your API

The "deprecated" extension can now be used under "Endpoint" models in the API. An easy way of getting familiar as to where to write the extension is to use the AMF Model Playground. An extension that isn't under the nodes allowed in the "AnnotationMapping" will be parsed as a "CustomDomainProperty".

openapi: 3.0.3
info:
title: "Semantic Extension example API"
version: 1.0.0
paths:
/v1/paginated:
description: "Deprecated endpoint"
# Using my "deprecated" semantic extension to add semantic information to the EndPoint
x-deprecated:
replaceFor: "v2/paginated"
message: "Deprecated because the response type has changed."
get:
responses:
"200":
description: "An annotated response object with the pagination annotation."
# As the AnnotationMapping doesn't apply to the "apiContract.Response" domain then this node will be parsed as a CustomDomainProperty
x-deprecated:
replaceFor: "v3/paginated"
message: "Deprecated because the response type has changed."

Processing Semantic Extensions in Code

Using Semantic Extensions in code requires:

  • Registering the AML Dialect where the extension is defined in an AMFConfiguration
  • Parsing the API . See Parsing for more info.
  • Transforming it with DEFAULT, EDITING or CACHE pipeline. See Transformation for more info.

This is show in the Semantic Extension Examples

Reading an extension from the Object Oriented interface

Reading a Semantic Extension is not as straightforward as reading "fixed" properties in an AMF model. To read an extension, the "Graph interface" should be used alongside the expanded URI used as "propertyTerm" value. This is show in the Semantic Extension Examples

Semantic Extension Usage Code Examples


Code extracted from the examples GitHub repository.