@openactive/data-models
Version:
Data models used to drive that OpenActive validator, developer documentation, and model libraries
563 lines (422 loc) • 12.7 kB
Markdown
# Model file format
## Model
Each model should have a file corresponding to it in `src/<version>/models`. The name of the file should correspond to the name of the object the model is describing.
e.g. for model **Event**, the file name should be **Event.json**.
### Properties
#### type
The type of object that this model describes. The name of the file should correspond to the name of the object the model is describing.
```json
{
"@type": "Event"
}
```
#### subClassOf
If this model is the subclass of another model or an external class _for which a local model does not exist_, this can be referenced here.
When calling `loadModel`, all of the parent model properties will be inherited.
```json
{
"@type": "BabyChanging",
"subClassOf": "#LocationFeatureSpecification"
}
```
```json
{
"@type": "FacilityUse",
"subClassOf": "https://schema.org/Product"
}
```
#### derivedFrom
A url pointing to any external objects that this model derives from.
Note this cannot be set when `subClassOf` is set to an external class.
```json
{
"derivedFrom": "https://schema.org/Event"
}
```
#### hasId
A `boolean` indicating whether this model has a JSON-LD `@id` property, which must always be in URL format.
```json
{
"hasId": true
}
```
#### sampleId
An example `@id`.
```json
{
"sampleId": "https://api.example.com/events/12345"
}
```
#### isJsonLd
Whether the this model is JSON-LD (defaults to `true`)
```json
{
"isJsonLd": false
}
```
#### requiredFields
An array of field names that are **REQUIRED** in the specification. This should only include fields that are explicitly mentioned in the OpenActive spec.
```json
{
"requiredFields": [
"id",
"@context",
"type"
]
}
```
#### requiredOptions
Where one of a collection of fields are required (e.g. an Event must have a `schema:startDate` or `oa:eventSchedule`), this can be specified here.
```json
{
"requiredOptions": [
{
"description": [
"While these properties are marked as optional, a data publisher must provide either a schema:startDate or specify a oa:eventSchedule for an event."
],
"options": [
"startDate",
"eventSchedule"
]
}
]
}
```
#### recommendedFields
An array of field names that are **RECOMMENDED** in the specification. This should only include fields that are explicitly mentioned in the OpenActive spec.
```json
{
"recommendedFields": [
"description",
"image",
"organizer"
]
}
```
#### inSpec
An array of field names that are defined in the specification. This should only include fields that are explicitly mentioned in the OpenActive spec.
This **MUST** include **ALL** required, recommended and optional fields.
```json
{
"inSpec": [
"id",
"@context",
"name"
]
}
```
#### notInSpec
An array of field names that are not defined for a particular model, where it inherits fields from a parent class.
```json
{
"notInSpec": [
"eventSchedule"
]
}
```
#### commonTypos
An key-value object of common typos for field names.
```json
{
"commonTypos": {
"offer": "offers"
}
}
```
#### fields
A key-value object of Fields (see below).
```json
{
"fields": {
"description": {
"fieldName": "description",
"requiredType": "https://schema.org/Text",
"example": "An fast paced game that incorporates netball, handball and football.",
"description": [
"A free text description of the event"
]
}
}
}
```
#### description
TODO
#### namedExamples
TODO
## Field
### Properties
#### fieldName
The name of the field. In the `Model.fields` or `Model.betaFields` layout, this should match the key of the field.
```json
{
"fieldName": "description"
}
```
#### model
The name of the model this field should conform to. This should reference another model that we have a local definition for.
```json
{
"model": "#Event"
}
```
If this is an array of models, you can represent it as below:
```json
{
"model": "ArrayOf#Event"
}
```
#### alternativeModels
Alternative models this field should conform to. This should reference another model that we have a local definition for.
```json
{
"model": "#Event",
"alternativeModels": [
"ArrayOf#Event"
]
}
```
#### requiredType
The schema.org type this field should conform to.
```json
{
"requiredType": "https://schema.org/url"
}
```
If this is an array of values, you can represent it as below:
```json
{
"requiredType": "ArrayOf#https://schema.org/url"
}
```
#### alternativeTypes
Alternative schema.org types this field can conform to.
```json
{
"requiredType": "https://schema.org/url",
"alternativeTypes": [
"ArrayOf#https://schema.org/url"
]
}
```
#### minDecimalPlaces
The minimum number of decimal places this field should have.
```json
{
"fieldName": "longitude",
"sameAs": "https://schema.org/longitude",
"requiredType": "https://schema.org/Number",
"minDecimalPlaces": 3,
"example": -0.083437,
"description": [
"The longitude of a location. For example -0.083437 (WGS 84)."
]
}
```
#### maxDecimalPlaces
The maximum number of decimal places this field should have.
```json
{
"fieldName": "price",
"sameAs": "https://schema.org/price",
"requiredType": "https://schema.org/Number",
"example": 33.00,
"maxDecimalPlaces": 2,
"description": [
"The offer price of the activity.",
"This price should be specified without currency symbols and as a floating point number with two decimal places.",
"The currency of the price should be expressed in the priceCurrency field."
]
}
```
#### minValueInclusive
The minimum value of a number, inclusive.
```json
"repeatCount": {
"fieldName": "repeatCount",
"sameAs": "https://pending.schema.org/repeatCount",
"requiredType": "https://schema.org/Integer",
"example": 3,
"description": [
"Defines the number of times a recurring Event will take place."
],
"minValueInclusive": 1
},
```
#### valueConstraint
A specific constraint on the value of the property.
Available constraints are:
##### `UriTemplate`
A RFC 6570 compliant Uri Template represented as a string.
```json
{
"fieldName": "idTemplate",
"sameAs": "https://openactive.io/idTemplate",
"requiredType": "https://schema.org/Text",
"example": "https://api.example.org/session-series/123/{startDate}",
"description": [
"An RFC 6570 compliant URI template that can be used to generate a unique identifier (`@id`) for every event described by the schedule. This property is required if the data provider is supporting third-party booking via the Open Booking API, or providing complimentary individual `subEvent`s."
],
"valueConstraint": "UriTemplate"
},
```
##### `UUID`
A lowercase universally unique identifier represented as a string. RFC 4122 Section 3 requires that UUID characters be generated in lower case.
```json
{
"fieldName": "identifier",
"sameAs": "https://schema.org/identifier",
"requiredType": "https://schema.org/Text",
"example": "123e4567-e89b-12d3-a456-426614174000",
"description": ["The Order UUID of the Order, OrderQuote or OrderProposal, which is required within the Orders feed."],
"valueConstraint": "UUID"
},
```
#### allowReferencing
Allow the property value to be an IRI referencing the `@id` of a JSON-LD object in another feed.
```json
"superEvent": {
"fieldName": "superEvent",
"sameAs": "https://schema.org/superEvent",
"model": "#Event",
"allowReferencing": true
},
```
#### requireReferencingInValidationMode
The value of this property must be an IRI in the specified validation modes.
```json
"orderedItem": {
"fieldName": "orderedItem",
"sameAs": "https://schema.org/orderedItem",
"model": "#Event",
"allowReferencing": true,
"requireReferencingInValidationMode": ["C1Request", "C2Request", "PRequest", "BRequest", "OrdersFeed"]
},
```
#### requiredContent
If this property must be set to a specific value, this can be specified here.
```json
{
"fieldName": "type",
"requiredType": "https://schema.org/Text",
"requiredContent": "Event",
"description": "",
"example": "Event"
}
```
#### description
An array of strings (one per paragraph), describing this field.
```json
{
"description": [
"A URL to a web page (or section of a page) that describes the event."
]
}
```
#### example
An example value of this field, for documentation.
```json
{
"fieldName": "url",
"requiredType": "https://schema.org/url",
"description": [
"A URL to a web page (or section of a page) that describes the event."
],
"example": "https://example.com/event/1234"
}
```
#### options
If this property must be set to a specific value picked from a list (e.g. an `enum`), the list values can be specified here.
```json
{
"fieldName": "eventStatus",
"requiredType": "https://schema.org/url",
"description": [
"The status of an event. Can be used to indicate rescheduled or cancelled events"
],
"options": [
"https://schema.org/EventCancelled",
"https://schema.org/EventPostponed",
"https://schema.org/EventRescheduled",
"https://schema.org/EventScheduled"
],
"example": "https://schema.org/EventScheduled"
}
```
#### inheritsTo
If this property allows an object to pass values down for inheritance by the child, you can specify this in a number of ways.
If all fields are inheritable:
```json
{
"fieldName": "subEvent",
"inheritsTo": "*"
}
```
To specify a blacklist of fields:
```json
{
"fieldName": "subEvent",
"inheritsTo": {
"exclude": ["id", "identifier", "subEvent", "superEvent"]
}
}
```
To specify a whitelist of fields:
```json
{
"fieldName": "subEvent",
"inheritsTo": {
"include": ["name", "description", "startDate", "endDate"]
}
}
```
`exclude` takes precedence over `include`.
#### inheritsFrom
If this property allows an object to inherit properties from it, you can specify this in a number of ways.
If all fields are inheritable:
```json
{
"fieldName": "superEvent",
"inheritsFrom": "*"
}
```
To specify a blacklist of fields (anything not in this list will be inheritable):
```json
{
"fieldName": "superEvent",
"inheritsFrom": {
"exclude": ["id", "identifier", "subEvent", "superEvent"]
}
}
```
To specify a whitelist of fields (anything not in this list will not be inheritable):
```json
{
"fieldName": "subEvent",
"inheritsFrom": {
"include": ["name", "description", "startDate", "endDate"]
}
}
```
`exclude` takes precedence over `include`.
#### deprecationGuidance
If this field has been deprecated, `deprecationGuidance` must be provided:
```json
{
"fieldName": "ageRange",
"deprecationGuidance": "Use `ageRestriction` instead of `ageRange` within the `Offer` for cases where the `Offer` is age restricted."
}
```
Note that deprecation is different from schema.org's `supersededBy`, as deprecation can occur for a specific use of the property within a particular type rather than the entire property.
## Namespace resolution
`sameAs` is REQUIRED, and must reflect the `fieldName` within the relevant namespace.
## DEPRECATED Namespace resolution
> Although the section below still reflects the inner workings of the validator, `sameAs` is now REQUIRED to remove ambiguity and make the model files easier to parse by various tools.
> It is expected that future versions of the OpenActive validator library will remove the namespace resolution logic specified below, and instead use the `sameAs` value provided.
For each field within the model, the rules of resolution are thus:
* *IF* `sameAs` is set on the field, use the namespace in there (see [example](https://github.com/openactive/data-models/blob/d5deb89c2395ba770b8cd943dedda9e996f76ac0/versions/2.x/models/Event.json#L115)) (the `activity` field is defined in the OA namespace, but `Event` is schema.org)
* *ELSE IF* `derivedFrom` is set for the model, use the namespace in there (see [example](https://github.com/openactive/data-models/blob/06a0516f2f228d2045e63530c7754df35d3810f5/versions/2.x/models/EntryPoint.json#L3)
* *ELSE IF* `derivedFrom` is set for a model further up the hierarchy as is specified via `subClassOf`, use the namespace in there
* *ELSE IF* `subClassOf` at the base of the hierarchy is an external class, use the namespace in there
* *ELSE* assume the field is in the OA namespace
If the same field has been defined in two different namespaces (e.g. in both "`schema:`" and "`oa:`"), the oa.jsonld file would not be able to be generated, and the unit tests produce the error "namespaces should not have fields in multiple namespaces".
Where the `sameAs` namespace is the same as the `derivedFrom` namespace, the use of `sameAs` is redundant.