Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
# Roles / namespaces / annotations in `v3-engine`
|
2024-04-10 11:57:25 +03:00
|
|
|
|
|
|
|
In V2 we created a schema per role.
|
|
|
|
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
In V3 we create one big schema at build time, where some nodes are annotated
|
|
|
|
with either `generic` info, or `namespaced` info that only applies to specific
|
|
|
|
roles.
|
2024-04-10 11:57:25 +03:00
|
|
|
|
|
|
|
The types for these annotations come from the `lang-graphql` crate, where they
|
|
|
|
are associated types on the `SchemaContext` trait.
|
|
|
|
|
|
|
|
This example used in tests for `lang-graphql` shows a schema with no
|
|
|
|
annotations. It uses a `Namespace` type to differentiate different scopes,
|
|
|
|
however since it has no annotations this won't do anything meaningful:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
impl SchemaContext for SDL {
|
|
|
|
type Namespace = Namespace;
|
|
|
|
type GenericNodeInfo = ();
|
|
|
|
type NamespacedNodeInfo = ();
|
|
|
|
```
|
|
|
|
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
The `engine` itself uses the `GDS` type, and so we can use the following
|
|
|
|
annotations:
|
2024-04-10 11:57:25 +03:00
|
|
|
|
|
|
|
```rust
|
|
|
|
impl gql_schema::SchemaContext for GDS {
|
|
|
|
type Namespace = Role;
|
|
|
|
type GenericNodeInfo = types::Annotation;
|
|
|
|
type NamespacedNodeInfo = Option<types::NamespaceAnnotation>;
|
|
|
|
```
|
|
|
|
|
|
|
|
Note that our `Namespace` type is `Role` - this means that the engine attached
|
|
|
|
useful information per role, so we can add select permissions for a field that
|
|
|
|
only apply to the `user-1` role, for instance.
|
|
|
|
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
(incidentally, there is a comment on the `SchemaContext` trait suggesting
|
|
|
|
`Namespace` is renamed to `Scope` or `Role` - this seems like a useful move to
|
|
|
|
make all this clearer, personally `Namespace` makes me think about different
|
|
|
|
subgraphs or something)
|
2024-04-10 11:57:25 +03:00
|
|
|
|
|
|
|
## What is an annotation then, concretely?
|
|
|
|
|
|
|
|
The change I have recently been working on is to add preset arguments to
|
|
|
|
commands. This means that given a `delete_user` command with a `user_id: Int`
|
|
|
|
argument, we can preset the value for certain roles.
|
|
|
|
|
|
|
|
For instance, we might want a `user-1` role to only be able to delete
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
themselves, so we'd preset `user_id` with
|
|
|
|
`{ "sessionVariable": "x-hasura-user-id" }`.
|
2024-04-10 11:57:25 +03:00
|
|
|
|
|
|
|
Previous to this change, when building the schema for the Command, we'd use
|
|
|
|
`builder.allow_all_namespaced` to create it, like
|
|
|
|
|
|
|
|
```rust
|
|
|
|
builder.allow_all_namespace(command_schema_stuff, None)
|
|
|
|
```
|
|
|
|
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
Instead, for our example, we'd use `conditional_namespaced` like this (excuse my
|
|
|
|
pseudo-Rust):
|
2024-04-10 11:57:25 +03:00
|
|
|
|
|
|
|
```rust
|
|
|
|
let role_annotations = HashMap::new();
|
|
|
|
|
|
|
|
role_annotations.insert("user-1", Some(ArgumentPresets { "user_id":
|
|
|
|
"x-hasura-role-id" }));
|
|
|
|
|
|
|
|
role_annotations.insert("admin", None);
|
|
|
|
|
|
|
|
builder.conditional_namespaced(command_schema_stuff, role_annotations)
|
|
|
|
```
|
|
|
|
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
Here, we've added an annotation for `user-1` with some useful information we can
|
|
|
|
use later when receiving and running queries. We've also added a `None`
|
|
|
|
annotation for `admin` - this means there'll be no useful information later, but
|
|
|
|
we're still signalling that we want this `Command` to work for `admin` users. If
|
|
|
|
we had a `user-2` role in the schema, they wouldn't be able to use the command.
|
2024-04-10 11:57:25 +03:00
|
|
|
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
## Removing items from the GraphQL schema, per role
|
2024-04-10 11:57:25 +03:00
|
|
|
|
|
|
|
By adding or omitting keys from the `role_annotations` above, we've made our
|
|
|
|
command appear or disappear from the GraphQL schema. This "snipping" as such,
|
|
|
|
happens in the `normalize_request` function in `lang-graphql`.
|
|
|
|
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
The important thing to know here is that `lang-graphql` code does not know about
|
|
|
|
`GDS` or our `NamespaceAnnotation` type. All it has to act on is whether a
|
|
|
|
`Role` (or `Namespace`, to it's eyes) has a key in any namespaced annotations or
|
|
|
|
not. Because we're using associated types the contents are "protected" from
|
2024-04-10 11:57:25 +03:00
|
|
|
`lang-graphql` and so it can't peek inside.
|
|
|
|
|
|
|
|
We're going to want the `user_id` argument to disappear from `user-1`'s schema
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
|
2024-04-10 11:57:25 +03:00
|
|
|
- we do this by using `conditional_namespaced` when contructing schema for the
|
|
|
|
`user_id` command argument itself:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
let role_annotations = HashMap::new();
|
|
|
|
|
|
|
|
// insert an empty annotation for `admin` to make sure the argument remains in
|
|
|
|
the schema
|
|
|
|
role_annotations.insert("admin", None);
|
|
|
|
|
|
|
|
// don't add one for `user-1`, so it disappears from the schema (as it has been
|
|
|
|
replaced with the preset value)
|
|
|
|
builder.conditional_namespaced(command_argument_schema_stuff, role_annotations)
|
|
|
|
```
|
|
|
|
|
|
|
|
## Reading the annotations at request time
|
|
|
|
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
Everything before here happens at "compile time" for the engine, so we do it all
|
|
|
|
once at startup and it remains static for the lifetime of the application.
|
2024-04-10 11:57:25 +03:00
|
|
|
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
At some point we are going to need to
|
|
|
|
[serve a request](https://github.com/hasura/v3-engine/blob/main/engine/src/execute.rs#L170)
|
|
|
|
though. The steps are as follows:
|
2024-04-10 11:57:25 +03:00
|
|
|
|
|
|
|
- Receive request
|
|
|
|
- Parse into a GraphQL query
|
|
|
|
- Normalize the query
|
|
|
|
- Generate IR
|
|
|
|
- Construct a query plan
|
|
|
|
- Execute / explain the query plan
|
|
|
|
|
|
|
|
The `normalize` step was mentioned earlier - it takes place in `lang_graphql`
|
|
|
|
and combines the query with the role information to remove all irrelevant
|
|
|
|
namespace information from the query, and snip any parts of the schema that the
|
Format everything with Prettier. (#530)
I found myself wanting to rewrite JSON files with `sed`. The problem is,
then I want to run a formatter over them afterwards, and this will
change the whole file, not just the area I touched.
I would like to propose the nuclear option in remedying this: format
everything now. This is a very large change that should make it easier
to keep files to a consistent format in the future.
I have chosen to use Prettier for this because (a) it has a useful
`--write` command and (b) it also does GraphQL, Markdown, YAML, etc.
I've elected to exclude two sets of files:
1. `crates/custom-connector/data/*.json`, because they are actually
multiple JSON objects, one per line, which Prettier cannot parse.
2. `crates/lang-graphql/tests/**/*.graphql`, because it contains invalid
GraphQL, and the parser is intended to work with strangely-formatted
GraphQL.
The main changes are standardizing whitespace, adding a newline at the
end of files, and putting JSON arrays on one line when they fit.
V3_GIT_ORIGIN_REV_ID: 92d4a535c34a3cc00721e8ddc6f17c5717e8ff76
2024-04-30 17:58:09 +03:00
|
|
|
current role can't see.
|
2024-04-10 11:57:25 +03:00
|
|
|
|
|
|
|
Generally the helpful place for our annotations is in generating IR
|
|
|
|
(intermediate representation, compiler fans). For our commands change, we can
|
|
|
|
look up the `ArgumentPresets` we stored earlier like
|
|
|
|
[this](https://github.com/hasura/v3-engine/pull/340/files#diff-f01744b02938317df22c7bc991717ae20a397f623c387332f103a30d1c0d2dc9R104).
|
|
|
|
|
|
|
|
```rust
|
|
|
|
match field_call.info.namespaced {
|
|
|
|
None => {}
|
|
|
|
Some(NamespaceAnnotation::ArgumentPresets(argument_presets)) => {
|
|
|
|
// use `argument_presets` for current role to generate IR
|
|
|
|
...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The IR will then be created from a mixture of the schema for the user's role,
|
|
|
|
and any arguments etc from their request.
|