Skip to content

Commit f317bc7

Browse files
authored
add clarification on arrows vs subject relations (#504)
1 parent e927fa0 commit f317bc7

2 files changed

Lines changed: 71 additions & 1 deletion

File tree

app/spicedb/concepts/schema/page.mdx

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ definition document {
9595

9696
### Subject Relations
9797

98+
_You can express similar logic with [Arrows](#--arrow); see [Arrows vs Subject Relations](#arrows-vs-subject-relations)._
99+
98100
In the example below, the `owner` relation allows you to grant "roles" to specific subjects and also _sets_ of subjects.
99101

100102
```zed
@@ -261,6 +263,8 @@ permission can_only_read = reader - writer
261263

262264
#### `->` (Arrow)
263265

266+
_You can express similar logic with [Subject Relations](#subject-relations); see [Arrows vs Subject Relations](#arrows-vs-subject-relations)._
267+
264268
Imagine a schema where a document is found under a folder:
265269

266270
```zed
@@ -617,6 +621,72 @@ This convention is useful for:
617621
- Valid: `_ab`, `_private`, `_internal_relation`, `_helper123`
618622
- Invalid: `_` (too short), `_a` (too short), `_trailing_` (cannot end with underscore)
619623

624+
## Notes on syntax
625+
626+
### Arrows vs Subject Relations
627+
628+
[Arrows](#--arrow) and [Subject Relations](#somethingelse) are very similar constructs: they
629+
both let you walk across a relation to indicate that one definition should be connected to
630+
another via a relationship.
631+
632+
For the most part, they are functionally equivalent: most ideas that can be expressed with a
633+
subject relation can be expressed with an arrow and vice versa. For example, from the perspective
634+
of asking whether `user:alice` can `edit` the resource `document:doc1`, these two schemas are
635+
equivalent:
636+
637+
```zed
638+
// Subject Relations
639+
definition user {}
640+
641+
definition group {
642+
relation member: user
643+
}
644+
645+
definition document {
646+
relation editor: group#member
647+
permission edit = editor
648+
}
649+
650+
// With test tuples:
651+
// group:eng#member@user:alice
652+
// document:doc1#editor@group:eng#member
653+
```
654+
655+
and:
656+
657+
```zed
658+
// Arrows
659+
definition user {}
660+
661+
definition group {
662+
relation member: user
663+
}
664+
665+
definition document {
666+
relation editor: group
667+
permission edit = editor->member
668+
}
669+
670+
// With test tuples:
671+
// group:eng#member@user:alice
672+
// document:doc1#editor@group:eng
673+
```
674+
675+
There's two meaningful ways that they differ:
676+
677+
- In the Subject Relation variant,
678+
you can directly check the `document:doc1#editor@group:eng#member` relationship, which
679+
tells you directly that all members of the `eng` group have `editor` on the document.
680+
- When writing relationships in the Subject Relation variant, you need to specify
681+
the `optional_subject_relation` field in the [`SubjectReference`] on the `WriteRelationships`
682+
request. This is one additional piece of bookkeeping.
683+
684+
#### Should I use Arrows or Subject Relations?
685+
686+
Because they're mostly equivalent, we recommend choosing whichever pattern makes sense to you
687+
at the beginning and then sticking with that convention. They do not differ in terms of Check and
688+
Lookup behavior or performance.
689+
620690
## Comments
621691

622692
### Documentation Comments

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,5 @@
5757
"typescript": "^5.9.3",
5858
"yaml-loader": "^0.8.1"
5959
},
60-
"packageManager": "pnpm@10.28.1"
60+
"packageManager": "pnpm@10.28.2"
6161
}

0 commit comments

Comments
 (0)