-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Repeatable directives #472
Conversation
@OlegIlyenko I need a couple more days to think about #472 vs #471 vs keep everything as is.
|
@IvanGoncharov thanks a lot for your feedback and for taking your time to review the PR! These are good points. I think the reason I used That said, I also think that your suggestion has a good argument (default that represents the prevalent use-case). So I think I don't have a strong preference between these two alternatives. Maybe you have some good examples of non-standard directives that are widely used and either need to be unique or non-unique? (would be interesting to compare both cases). Also, you be interesting to hear opinions on this aspect from other reviewers. Regarding Also in my experience, directives are very rarely authored in the SDL. Most of the time I worked with and saw them used in the host language. From this perspective most of the time directive-definitions-in-sdl show up in the rendered output of actual schema (in this case I would prefer more explicit |
@OlegIlyenko In majority of cases directives are used to attach additional metadata to the SDL entity like: A few examples of unique directives from my own tools would be:
If we decide to add
In case of describing constrains on data I totally agree with you that everything should be unconstrained by default.
Not sure about other language but in JS it looks like defining directives in SDL is quite popular approach: |
I think a near-ideal English word would be I also wonder if, instead of adding a language keyword, we should instead allow directives on directive definitions. Then you'd have something like:
I agree with @IvanGoncharov that by default, most directives will be unique per location. A couple of potential directive examples:
As I think it'll be easier to implement unique directives, I suspect it's better if by default the implementer doesn't have to worry about merging them. I'm not totally sure we'll ever get to a set of 100% consistent directive-merging rules that work for all use cases. But if we did this, it would be easy if we decided, say, that |
@mjmahone I like directive @example repeatable on OBJECT | INTERFACE
It creates one more source of recursion in GraphQL schema and requires to add additional validation rules. As for
This why I think |
@IvanGoncharov those arguments are pretty convincing to me. It does end up potentially opening up a class of "things we want to add to directive definitions", and this argument basically means this entire class cannot be experimentally added via directives first, but instead must be added to the language. I can't immediately think of another example that lives in this class though, so maybe this is indeed the only thing in the entire class of "additions to directive definitions" we would want to add. |
@mjmahone I also like
I thought about this as well, but I think I would agree with @IvanGoncharov's arguments. I feel that the syntax will get quite confusing in SDL. ATM I also can't think of other use-cases for directives-on-directives. |
To follow up from the last WG session: a Next steps are to revise the spec change and create a GraphQL.js PR to ensure there are no hidden issues with implementation! |
FYI: I just implemented it for the reference implementation: graphql/graphql-js#1541 |
spec/Section 4 -- Introspection.md
Outdated
@@ -417,3 +418,4 @@ Fields | |||
locations this directive may be placed. | |||
* `args` returns a List of `__InputValue` representing the arguments this | |||
directive accepts. | |||
* `repeatable` must return a Boolean which permits using the directive multiple times at the same location. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we already have isDeprecated
as boolean predicate I think we should follow this naming convention and name it isRepeatable
.
As a bonus, it would be immediately clear that it's boolean value and not a something else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with both alternatives. Though, I also find consistency argument quite compelling.
I renamed it for now 5c8c4bd, but I can chnage it later if somebody raises a concern.
I wonder what others think about it?
spec/Section 3 -- Type System.md
Outdated
```graphql example | ||
directive @example repeatable on OBJECT | INTERFACE | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great to include a more complex example that illustrates how repeatable
is useful or at least add a note that directive order is significant and you can use it to create chains of directives.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I extended the example 218e0da and the description 477919e.
I struggled with it a bit since I find it hard to strike the right balance between completeness of the example including its description and succinct focused content required from a perspective of the specification. For this reason I also hesitated mentioning the order significance since it has its own dedication section with a separate example.
WDYT?
BTW, I tried repeatable directives in one of my projects: https://github.com/OlegIlyenko/graphql-gateway/blob/master/testSchema.graphql#L6-L15 It looks so much better now <3 In comparison to the previous version Now I also can distribute |
does that mean a directive can be repeatable on an object but must be unique on a field? |
@michaelstaib no, in a current form "repeatable" is a property of a directive regardless of the location. For example: directive @example repeatable on OBJECT | FIELD_DEFINITION
|
But than the text should be changed because may be defined as repeatable per location with the sounds like you could do something like the following: directive @example repeatable on OBJECT | unique on INTERFACE I know that this example is non-sense but it sounded to me like that was implied. |
spec/Section 3 -- Type System.md
Outdated
@@ -1660,6 +1660,21 @@ fragment SomeFragment on SomeType { | |||
} | |||
``` | |||
|
|||
A directive may be defined as repeatable at any permitted location with the `repeatable` | |||
keyword. Repeatable directives often useful when the same directive should be used with | |||
different arguments at the one location, especially in cases where additional information |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
different arguments at the one location, especially in cases where additional information | |
different arguments at a single location, especially in cases where additional information |
spec/Section 3 -- Type System.md
Outdated
A directive may be defined as repeatable at any permitted location with the `repeatable` | ||
keyword. Repeatable directives often useful when the same directive should be used with | ||
different arguments at the one location, especially in cases where additional information | ||
need to be provided in a form of directive via a type or a schema extension: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to be provided in a form of directive via a type or a schema extension: | |
needs to be provided to a type or schema extension through a directive: |
spec/Section 4 -- Introspection.md
Outdated
@@ -417,3 +418,4 @@ Fields | |||
locations this directive may be placed. | |||
* `args` returns a List of `__InputValue` representing the arguments this | |||
directive accepts. | |||
* `isRepeatable` must return a Boolean which permits using the directive multiple times at the same location. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* `isRepeatable` must return a Boolean which permits using the directive multiple times at the same location. | |
* `isRepeatable` must return a Boolean that indicates if a directive may be used repeatedly at a single location. |
spec/Section 5 -- Validation.md
Outdated
@@ -1440,7 +1440,7 @@ query @skip(if: $foo) { | |||
**Formal Specification** | |||
|
|||
* For every {location} in the document for which Directives can apply: | |||
* Let {directives} be the set of Directives which apply to {location}. | |||
* Let {directives} be the set of Directives which apply to {location} and not marked as `repeatable`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Let {directives} be the set of Directives which apply to {location} and not marked as `repeatable`. | |
* Let {directives} be the set of Directives which apply to {location} and are not `repeatable`. |
@leebyron @IvanGoncharov the title of this PR has become misleading as the change evolved to |
Co-authored-by: Benedikt Franke <benedikt@franke.tech>
b0e58d6
to
8391a1e
Compare
This proposal directly relates to a discussion in #429. As was discussed at the latest WG meeting, I'm creating several alternative proposals. This one implements proposed solution
4. Limit the validation to only these directives that are explicitly marked as "unique". This implies that we need to introduce a new option in the directive definition
.It limits the scope of "Directives Are Unique Per Location" to directives that are explicitly marked as
unique
.This proposal is mutually exclusive with other alternative proposals:
@skip
,@include
and@deprecated
directives ([RFC] Limit uniqueness to@skip
,@include
and@deprecated
directives #471)@leebyron @IvanGoncharov @jjergus I would appreciate your reviews.
Closes #429
Closes #471