Linking related data

This recipe shows how to express relationships between different kinds of schema instance — uniqueness, referential integrity, cascading behaviour, and required combinations of properties — using features the schema system supports today.

When to use these features

Use unique when no two items of the same type should share the same value for a property — an email on a Person, a slug on a Project, a handle on a User. Uniqueness is scoped per host and per type, so two different types can share a value without conflict.

Use references when a property on one item must point at an item of another type that already exists — a Comment pointing at a Post, a Task pointing at a Project. The platform rejects writes whose reference points at nothing.

Use cascade or restrict rules to decide what happens when the referenced item is deleted or updated — cascade propagates the change, restrict refuses it.

Use group constraints when several properties on the same item must satisfy a combined rule — "exactly one of userName or email must be present", "at least one of phone or address".

Unique constraints

A unique property rejects writes that would introduce a duplicate value for the same governed type:

<li itemprop="property" itemscope itemtype="https://pagelove.org/Property">
  <meta itemprop="name" content="slug">
  <meta itemprop="type" content="https://schema.host/Text">
  <meta itemprop="cardinality" content="1..1">
  <meta itemprop="unique" content="true">
</li>

A PUT that would create a second Project with slug="launch" fails with a 422 Unprocessable Entity. The first Project is unaffected.

Composite uniqueness — "the combination of these two properties must be unique" — is expressed by giving each property the same group name in its unique value instead of "true":

<meta itemprop="unique" content="staff-id-per-tenant">

Properties that share a non-"true" group name form a composite uniqueness constraint across their values.

Referential integrity

A property with a references declaration must point at an existing item of the named type:

<li itemprop="property" itemscope itemtype="https://pagelove.org/Property">
  <meta itemprop="name" content="project">
  <meta itemprop="type" content="https://schema.host/URL">
  <meta itemprop="cardinality" content="1..1">
  <meta itemprop="references" content="https://example.com/Project">
</li>

A PUT whose project property points at a URL that does not resolve to a Project fails with a 422. The error describes which reference was unresolved.

Cascade and restrict on delete

When a referenced item is deleted, the platform needs a policy for what to do with the items that point at it. Two choices:

The policy lives on the referencing property:

<meta itemprop="onDelete" content="restrict">

Restrict is the default for required references. Cascade is usually explicit. A schema with a required (1..1) reference that cascades will delete the referencing item when its target is deleted, because it has nowhere else to point.

Group constraints

A group constraint applies to a combination of properties on the same item — "exactly one of these must be present", "at least one of these", "at most one". The constraint is declared on the parent schema rather than on any individual property, because it spans several:

<div itemprop="constraint" itemscope itemtype="https://pagelove.org/GroupConstraint">
  <meta itemprop="group" content="contact">
  <meta itemprop="property" content="email">
  <meta itemprop="property" content="phone">
  <meta itemprop="cardinality" content="1..n">
</div>

The example says "at least one of email or phone must be present on every item governed by this schema". The cardinality shape is the same as a property cardinality: 0..1, 1..1, 0..n, 1..n.

See also