Composable Schemas (Preview)
This is a preview feature whose functionality is subject to change before general release.
In zed version v0.27.0, we introduced a compilation command:
zed preview schema compile some-schema.zed
There are three new pieces of syntax: [import statements][Import Statements], [partial declarations][Partial Declarations], and [partial references][Partial References].
This is a simple schema that demonstrates all three features:
import "./subjects.zed"
partial view_partial {
relation user: user
permission view = user
}
definition resource {
...view_partial
relation organization: organization
permission manage = organization
}
Compiling the above with zed preview schema compile
will produce an output schema that looks like:
definition user {}
definition organization {}
definition resource {
relation user: user
permission view = user
relation organization: organization
permission manage = organization
}
This compilation step introduces a new set of features that allow you to break down your schema, which helps make organizing and collaborating on a schema easier.
Import Statements
Import statements allow you to break down a schema along the lines of top-level declarations.
// An import keyword followed by a quoted relative filepath
import "./one.zed"
// Note that a bare filename works as a relative path
import "two.zed"
// The imports are included by the compilation process, which means that
// they can be referenced by other definitions
definition resource {
relation user: user
relation organization: organization
permission view = user + organization
}
Good to Know
- Import references must be within the folder where
zed
is invoked. - Import cycles are treated as errors.
- All definitions in all imported files are pulled in. Any duplicate definitions will cause an error.
Partials
Partial declarations and references provide a means of decomposing a schema along lines that cross definition boundaries. This can be useful for separating out a schema by team or domain concern, for example.
Partial Declarations
A partial declaration is a top-level block that is declared using the partial
keyword.
It can contain relations, permissions, and partial references just like a definition
block, but its contents
must be referenced by a partial reference to show up in the compiled schema.
partial view_partial {
...some_other_partial
relation user: user
permission view = user
}
Good to Know
- Any partial that isn't referenced is ignored by the compilation process.
- Partial declarations can contain partial references, allowing for partials to be composed.
Partial References
A partial reference takes a partial
and includes the relations and permissions defined in that partial.
It works similarly to JS spread syntax (opens in a new tab)
or python's dictionary unpacking (opens in a new tab).
This syntax:
partial view_partial {
relation user: user
permission view = user
}
definition resource {
...view_partial
}
is equivalent to this declaration:
definition resource {
relation user: user
permission view = user
}
Good to Know
- Duplicate relations and permissions introduced by a partial reference are treated as errors.
- Circular references between partials are treated as errors.
- You can only reference partial declarations. Attempting to reference other declaration types (e.g. a definition or a caveat) with a partial reference will result in a error.
Limitations
SpiceDB WriteSchema
calls cannot interpret import
or partial
syntax. If using the new syntax, you must
build the schema using compile
before it can be submitted.