Preamble

The preamble (introductory SOML section) includes metadata and prefixes.

Schema Metadata

You can provide some info (metadata) about the schema.

id:          /soml/some-domain
label:       Some Domain schema
created:     2019-04-15
updated:     2019-05-10
creator:     http://ontotext.com
versionInfo: 1.0

Only id is mandatory, the other fields are optional.

  • id is used for SOML operations (create, update, delete) by the SOaaS services. It should start with /soml/

  • versionInfo is the version of the schema (SOML instance and corresponding ontology), not a version of the SOML language

The rest of the preamble defines prefixes (namespaces) that are used to map object and prop names to IRIs (URLs) as used in RDF.

Special Prefixes

specialPrefixes:
  base_iri:     http://example.org/resource/
  vocab_iri:    http://example.org/vocabulary/
  vocab_prefix: voc
  ontology_iri: http://example.org/vocabulary
  shape_iri:    http://example.org/shape/

The special prefixes (namespaces) include:

  • base_iri: base IRI for data (resources), used in SOML characteristics such as type and prefix. We currently use full IRIs in GraphQL queries and responses, but in the future may shorten them using the base (see Naming Convention and IRI Processing).

  • vocab_iri: default namespace for vocabulary (ontology) terms, i.e. object and prop names. SOML allows the use of multiple ontologies (see Prefixes) through underscore prefixes like pfx_prop, and one of them is designated as default so it can be used without prefix.

  • vocab_prefix: prefix corresponding to the vocab IRI.

    • It must be used in SOML for prop names that conflict with a reserved word (see Reserved Words)

    • It is also useful in languages that don’t have such a concept (eg Turtle), as we don’t like to use an empty prefix

The following IRIs may be used in the future:

  • ontology_iri: RDF Ontology IRI, used to make statements about the ontology. Typically it’s the same as the vocab IRI but without a trailing slash or hash.

  • shapes_iri: RDF Shapes IRI: all generated shapes live under this IRI

Predefined Prefixes

SOML predefines a few commonly used prefixes such as dct: gn: owl: rdf: xsd:, and some more exotic prefixes:

  • puml:: used by the rdfpuml diagramming tool

  • so:: in the future may transmit in JSONLD built-in SOML props like so:name and so:type

  • res:: in the future may transmit in JSONLD dynamic props calculated in queries

prefixes:
  # common prefixes
  so:    http://www.ontotext.com/semantic-object/
  res:   http://www.ontotext.com/semantic-object/result/
  dct:   http://purl.org/dc/terms/
  gn:    http://www.geonames.org/ontology#
  owl:   http://www.w3.org/2002/07/owl#
  puml:  http://plantuml.com/ontology#
  rdf:   http://www.w3.org/1999/02/22-rdf-syntax-ns#
  rdfs:  http://www.w3.org/2000/01/rdf-schema#
  skos:  http://www.w3.org/2004/02/skos/core#
  void:  http://rdfs.org/ns/void#
  wgs84: http://www.w3.org/2003/01/geo/wgs84_pos#
  xsd:   http://www.w3.org/2001/XMLSchema#

The Special Prefixes shown in the previous section and the prefixes shown above are predefined and may be used without having to define them (but can be overridden): This means that a valid SOML doesn’t need to define any prefixes.

  • A plain name like Obj or prop is mapped using vocab_iri, which by using the predefined prefixes maps to voc:Obj or voc:prop respectively, and thus to http://example.org/vocabulary/ IRIs.

  • Of course, in a real application you’d want to define your own special prefixes.

Prefixes

You can also define your own prefixes for your domain, eg:

prefixes:
  # schema-specific prefixes
  sw:  https://swapi.co/vocabulary/
  dbr: http://dbpedia.org/resource/
  dbo: http://dbpedia.org/ontology/

Rules:

  • Each prefix should conform to the Turtle grammar production PN_PREFIX

  • Prefixes should not mask defined IRI schemes such as http: https: mailto: ftp: mailto: urn: geo:. (In some cases you may want to break this guideline for convenience, eg the schema.org JSON-LD context defines a prefix geo: that breaks it)

Naming Convention and IRI Processing

Class and property names (the YAML key) play several important roles:

  • They are used in SOML to describe objects, properties and the connection between them.

  • They (together with prefixes and vocab_iri are used to derive RDF IRIs).

  • They are used in GraphQL as type and field names. pfx:name is translated to pfx_name to make it GraphQL and JSON friendly

If a name includes :, the part before it must be a defined prefix (see Prefixes).

The local parts of property and class names (part after : if any) must comply with the following naming conventions:

  • Prop names must start with a lowercase Unicode letter, and are recommended to follow a lowerCamelCase convention.

  • Class names must start with an uppercase Unicode letter, and are recommended to follow an UpperCamelCase (also called PascalCase) convention.

  • Both must conform to the Turtle grammar production PN_PREFIX. Please note that this is stricter than RDF and Turtle local name conventions.

  • In particular they cannot use punctuation chars such as :.-. If you need to use names that don’t conform to this (eg class Auto.Model or props birth-date or birth.date), use the class characteristic type or prop characteristic rdfProp. (You can also use them to map a user-friendly SOML name to a less readable RDF name in an underlying ontology.)

  • Cannot start with two underscores __, which is reserved for GraphQL introspection.

  • If they include an underscore, they cannot start with pfx_ where pfx: is a defined prefix. Use pfx:name if you meant that prefix, or voc:pfx_name if you meant the default vocab namespace (see Special Prefixes)

  • Cannot be a reserved word, see Reserved Words.

Names in SOML are converted to IRIs as follows:

  • If the prop has characteristic rdfProp, use that instead of the name.

  • If a name starts with a defined prefix pfx:, replace the prefix with the coresponding IRI.

  • Otherwise prepend vocab_iri.

Strings in the type and rdfProp characteristics are converted to IRIs as follows:

  • If the string starts with a defined IRI scheme, use it directly (absolute IRI).

  • Else if the string starts with a defined prefix pfx: , replace the prefix with the coresponding IRI (prefixed IRI).

  • Else if the string includes only Unicode alphanumerics and [-._], prepend vocab_iri (relative ontology IRI).

  • Else prepend base_iri (relative instance IRI). Typically such string will include / or # and is used in the type characteristic to designate a “business type” not defined in an ontology, eg a skos:ConceptScheme IRI.

GraphQL queries and JSON responses use absolute IRIs for iri fields. This includes:

  • the id field of every object, which is its IRI

  • fields of type iri (eg websiteUrl of a company) that reference external resources

  • the type field, which is the datatype of Literals or rdf:type of objects (most of the time you don’t need to specify these explicitly)

We have an idea to use Compact URIs (CURIEs) in the future to shorten GraphQL queries and JSON responses (see CURIE in Wikipedia and the CURIE W3C TR) but have not yet done so because this may cause confusion in some cases. If you’d like to use CURIEs, please send us feedback.

Reserved Words

The following reserved words cannot be used as prop names: id type lang value name:

  • id is the node IRI and is a mandatory field for every object (the GraphQL type ID! is used)

  • type is the rdf:type of objects or datatype of scalars

  • lang is the language tag of a Literal or langString

  • value is the value of a Literal

  • name is a uniform preferred name for an object

The following reserved words cannot be used as object names: Literal Object Nameable

  • Literal together with lang, type and value is used to represent an RDF literal

  • Object is an interface for common functionality: the presence of id and type

  • Nameable is an interface used for the presence of name

To use such prop/object names in the vocab namespace, you need to spell them in full, eg voc:type voc:name voc:Object.

GraphQL descr Directive

Objects and properties have label and descr. These are emitted separately in GraphQL, so they can be used more conveniently in a UI app.

  • Label comes before the object/prop as a “string”: that is a standard GraphQL feature.

  • Descr comes after the object/prop as a @descr directive.

For example, this SOML property:

prefName: {label: "Preferred name", min: 1, descr: "A single selected name"}

Is emitted in GraphQL as follows:

"Preferred name"
prefName: String! @descr(_:"A single selected name")

The directive is defined as follows:

directive @descr(_:String!) on FIELD_DEFINITION | OBJECT | INTERFACE

According to the GraphQL spec, directive values are not returned as part of GraphQL schema introspection. This problem is discussed in issue graphql-spec#300 and we added @descr as a use case, and return the directive value anyway.