Conventions
Every OURS resource is a JSON object that follows the same few conventions. They are FHIR’s conventions, reused so that existing tooling and existing instincts carry over.
Common fields
Section titled “Common fields”| Field | Type | |
|---|---|---|
resourceType |
string, required | Ontology, Model or Vocabulary. |
id |
string, required | Short identifier, unique within the ontology. |
url |
URL, required | The resource’s identity. See below. |
version |
string, required | The publisher’s own version, in the publisher’s own scheme. |
publisher |
string, optional | Who publishes it. Required on an Ontology. |
name |
string, optional | Human-readable name. Required on a Model and a Vocabulary. |
description |
string, optional | What it means, in prose, for a human reader. |
url is identity
Section titled “url is identity”A resource’s url is how everything else refers to it, and a consumer treats
two resources with the same url as the same thing. Three consequences follow.
Serve the resource at the URL it claims. A document fetched from one address that identifies itself as another gives a consumer two candidate identities and no rule for choosing.
Do not reuse a url for a different resource. Changing what lives at an
address is not a version bump, it is a substitution, and nothing pointing at
the old meaning will notice.
Do not move one casually. Every mapsTo, every $ref, and every consumer’s
stored reference points at the URL, so moving a resource breaks them the way
renaming a published API endpoint does.
Versioning
Section titled “Versioning”version is a string and the format does not impose a scheme. Semantic
versioning is a reasonable default and a date is a reasonable alternative for a
vocabulary that tracks an external release, as ISO 4217 does.
The version describes the resource, not the ontology as a whole. A model may
sit at 2.1.0 inside an ontology at 1.0.0; there is no requirement that they
move together.
Documents and bundles
Section titled “Documents and bundles”A document is what a consumer gets from one fetch. It is either a single
resource or a Bundle collecting several:
{ "resourceType": "Bundle", "type": "collection", "entry": [ { "fullUrl": "https://ours.example.org/models/person.json", "resource": { "resourceType": "Model", "id": "person" } } ]}| Field | Type | |
|---|---|---|
resourceType |
string, required | Always Bundle. |
type |
string, required | Always collection. OURS uses no other bundle type. |
entry |
array, required | May be empty. |
entry[].fullUrl |
URL, required | The entry’s url, repeated where a reader can see it without parsing the resource. |
entry[].resource |
object, required | An Ontology, Model or Vocabulary. |
Both packagings are correct. Serving one bundle of every model is one fetch and one cache entry; serving a file per model lets a consumer take only what it needs. Readers accept either, so this is a publishing decision rather than something a consumer has to be told in advance.
Saying “none” out loud
Section titled “Saying “none” out loud”An Ontology requires all three of models, vocabularies and mappings,
and a publisher who has none of something serves an empty collection rather
than dropping the pointer:
{ "resourceType": "Bundle", "type": "collection", "entry": [] }An absent URL cannot be told apart from one that has not been published yet, so a consumer meeting one has to decide whether to keep looking, ask someone, or give up. An empty bundle at a live URL is a definite answer, and the point of the format is that nobody should have to ask.
The per-alignment mapping field on mapsTo stays
optional, and the asymmetry is deliberate. There the alignment is already in
front of the reader, so the field’s absence says “no executable map for this
one” without ambiguity. It is only at the ontology root, where nothing else is
present to speak, that silence cannot be read.
Serving
Section titled “Serving”- Send
Content-Type: application/json. - Send
Access-Control-Allow-Origin, or browser-based consumers cannot read the ontology at all. - Set cache headers you can live with. A long
max-ageon a document you revise will serve the old one long after you have fixed it. - Keep the URLs stable, for the reasons above.