Skip to content

[RFC] Document Directives #556

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

langpavel
Copy link

@langpavel langpavel commented Jan 31, 2019

This addresses #410 Directives at the top of a SDL file

WIP

✔️ Required grammar and introspection changes included


```graphql example
@import(from: "./common")
@import(from: "./user")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should use @import directives as an example here.
Since some readers can think it a standard one and supported by GraphQL spec.
I think it would be better to use something like @someTopLevelDirective, @foo, @test, etc.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is most relevant example I wish to show and indeed it is my intent to push on some common way to do import. I can add note or warning below that import is not built-in

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @import will have meaning in a bunch of libraries almost immediately, and those meaning will probably immediately diverge, let's keep it out of the spec entirely. There aren't any descriptions of any other user-level directives in the spec.

The only other usage is @addedDirective and @example because they illustrate the usage without introducing a new concept.

In this case, you could call it @exampleDocumentDirective or even just @example

```

Unknown directives may be ignored, but it is recommended for services to fail
if directive is not recognized.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@langpavel It contradicts rules for all other directives:
https://facebook.github.io/graphql/June2018/#sec-Directives-Are-Defined

Personally, I think we shouldn't have any exceptions for top-level directives.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, this sentence can be dropped entirely, ok?

@@ -94,10 +94,14 @@ lines and uniform indentation with {BlockStringValue()}.
Document : Definition+

Definition :
- DocumentDirective
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- DocumentDirective
- DocumentDirectives

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, DocumentDirective (singular) is really what should be stated in grammar.

Copy link
Member

@IvanGoncharov IvanGoncharov Jan 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see now
Then I think it makes more sense to do

Document: Directives[Const] Definition+

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will prevent you from inserting document level directives into middle of document.
This may be problematic if you concatenate more documents into one.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moreover there is chicken egg problem, when you wish define document directive you cannot use it in same document

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moreover there is chicken egg problem, when you wish define document directive you cannot use it in same document

You can. Why not?
GraphQL doesn't care about order of things in SDL. This is perfectly valid:

scalar SomeScalar @someDirective

directive @someDirective on SCALAR

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you are right…

@@ -1094,3 +1095,24 @@ and operations.

As future versions of GraphQL adopt new configurable execution capabilities,
they may be exposed via directives.


## Document Directives
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think they should be a special case of directives.
They should be covered by: https://facebook.github.io/graphql/June2018/#sec-Language.Directives

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intent is place document level directives aside from others, there apply different rules:

  • Document directives may be repeated, others not.
  • Document level directives are top level AST Document DocumentNode.definitions nodes, other directives are listed in XxxNode.directives — this may need discussion

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document directives may be repeated, others not.

#472 add support of reputable directives.

Document level directives are top level AST Document DocumentNode.definitions nodes, other directives are listed in XxxNode.directives — this may need discussion

I think DocumentNode.directives makes more sense.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'd much rather see this compose with the repeatable directives change.

Moreover, even if we never gained repeatable directives, document-level driectives (such as @import) could always be expanded to take lists instead @imports(from: ["foo", "bar/baz"]). It's better to keep the total number of concepts down: if something looks like it should work in two contexts, but subtly works a different way in one of them, that's a spec bug.

@IvanGoncharov IvanGoncharov added the 💭 Strawman (RFC 0) RFC Stage 0 (See CONTRIBUTING.md) label Jan 31, 2019
@IvanGoncharov
Copy link
Member

I think we need to have a separator between top-level directives and rest of SDL file

@import(from: "./common")
@import(from: "./user")
---

type Query {
  foo: String
}

Similar to YAML: https://yaml.org/spec/1.1/#YAML%20directive/

Because without it we can cause some confusion:

@someDirective

scalar Url

@someDirective is top level directive but some user may think that @someDirective belongs to scalar definition especially since it looks very similar to decorators in JS and many other languages.

Plus I saw some people concatenate SDL files so if you have two files like this:

scalar SomeScalar

and

@someDirective

scalar AnotherScalar

We would get valid SDL:

scalar SomeScalar
@someDirective

scalar AnotherScalar

But parser will parse @someDirective as part of SomeScalar definition.
With 3 dashes we will have:

scalar SomeScalar
@someDirective
---
scalar AnotherScalar

The parser will error saying you can't use --- in the middle of the file.

If we decide to allow top-level directives we can always allow:

scalar SomeScalar

---
@someDirective
---

scalar AnotherScalar

@langpavel
Copy link
Author

Hmm, good point with grammar ambiguity, however I don't like --- separator,
What about new keyword document followed by document level directives?

Copy link
Contributor

@mjmahone mjmahone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's another question: most directives are either executable or schema directives: you can't use a schema-level directive inside an executable document, and vice versa. Which of these is the document directive? Is it neither? Why?

Basically: if I have a document with a bunch of fragments, should I be able to include a directive that modifies the schema? Why or why not?

@@ -1094,3 +1095,24 @@ and operations.

As future versions of GraphQL adopt new configurable execution capabilities,
they may be exposed via directives.


## Document Directives
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'd much rather see this compose with the repeatable directives change.

Moreover, even if we never gained repeatable directives, document-level driectives (such as @import) could always be expanded to take lists instead @imports(from: ["foo", "bar/baz"]). It's better to keep the total number of concepts down: if something looks like it should work in two contexts, but subtly works a different way in one of them, that's a spec bug.


```graphql example
@import(from: "./common")
@import(from: "./user")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @import will have meaning in a bunch of libraries almost immediately, and those meaning will probably immediately diverge, let's keep it out of the spec entirely. There aren't any descriptions of any other user-level directives in the spec.

The only other usage is @addedDirective and @example because they illustrate the usage without introducing a new concept.

In this case, you could call it @exampleDocumentDirective or even just @example

@mjmahone mjmahone dismissed their stale review February 1, 2019 16:01

Changes made make it no longer applicable

Base automatically changed from master to main February 3, 2021 04:50
@leebyron leebyron force-pushed the main branch 4 times, most recently from e5d241d to 6c81ed8 Compare April 23, 2021 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💭 Strawman (RFC 0) RFC Stage 0 (See CONTRIBUTING.md)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants