References
You can use the type REFERENCE alongside a reference property to let Unito know that
the potential values of a field are constrained to a given list. Unito will populate the list based on the items it
finds at the referenced relation's path, and use the selected referenced item's path as the value for the field.
As an example, say you have a pokémon that has an element field for which the value needs to be picked from a list of
potential elements. We'd expect the schema of the field to be similar to the following;
{
name: "element",
label: "Element",
type: FieldValueType.REFERENCE,
reference: {
name: "elements",
label: "Elements",
path: "/elements",
schema: {
label: "Element",
fields: [
{
name: "name",
label: "Name",
type: FieldValueType.STRING,
semantic: Semantic.DISPLAY_NAME,
}
]
}
}
}
This indicates that the list of values for the element field can be found at the /elements path.
{
"info": {},
"data": [
{
"path": "/elements/fire",
"fields": { "name": "Fire" },
},
{
"path": "/elements/water",
"fields": { "name": "Water" },
},
{
"path": "/elements/grass",
"fields": { "name": "Grass" },
},
{
"path": "/elements/electric",
"fields": { "name": "Electric" },
}
]
}
Any of the above paths can then be used as the value of the element field.
{
"element": "/elements/fire"
}
The values of reference fields are displayed as item summaries.
{
"element": {
"path": "/elements/fire"
}
}
Like any other field, references should be selectable.
{
"info": {},
"data": [
{
"path": "/pokemons/1",
"fields": { "element": { "path": "/elements/fire", "fields": { } } },
},
{
"path": "/pokemons/2",
"fields": { "element": { "path": "/elements/water", "fields": { } } },
}
]
}
Their fields should be selectable, too, using the special (.) delimiter.
{
"info": {},
"data": [
{
"path": "/pokemons/1",
"fields": { "element": { "path": "/elements/fire", "fields": { "name": "fire" } } },
},
{
"path": "/pokemons/2",
"fields": { "element": { "path": "/elements/water", "fields": { "name": "water" } } },
}
]
}
This simple example mimics what other systems would consider enums. But it can extends to much more complex use cases. You could use this pattern to reference the author of a book, or to update the list of invitees to an event. If the values need to be taken from a list, it likely is a reference!
Pointing to an existing relation
Instead of redeclaring the collection schema inline within each reference field, you can point to an existing relation elsewhere in the graph using a RelationPointer. This is useful when the referenced collection already exists as a relation on another item.
For example, say a project has a assignee field whose values come from the users relation on the parent workspace. Instead of duplicating the users schema, you can point to it:
{
name: "assignee",
label: "Assignee",
type: FieldValueType.REFERENCE,
reference: {
itemPath: "/workspaces/1",
relationName: "users",
}
}
This tells Unito that the list of valid values for assignee can be found by looking at the users relation on the item at /workspaces/1. The schema of the referenced collection is resolved from that relation, so there's no need to redeclare it.
Both forms (ReferenceRelation and RelationPointer) are valid for the reference property. Use a pointer when the collection already exists elsewhere in the graph; use an inline ReferenceRelation when it doesn't.