Skip to content
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

Directives for the schema definition language #114

Closed
fson opened this issue Aug 9, 2015 · 11 comments
Closed

Directives for the schema definition language #114

fson opened this issue Aug 9, 2015 · 11 comments

Comments

@fson
Copy link
Contributor

fson commented Aug 9, 2015

It is often useful to associate additional metadata with the schema. I suggest directives similar to those in GraphQL documents to be added to the schema definition language for this purpose.

The most common usecases for them are probably descriptions and deprecation reasons. But like normal GraphQL directives, they also provide an extension point for adding other metadata, such as additonal information about a connection as shown in this example.

interface Node
@doc(description: "Object with an ID")
{
  id: ID!
}

interface Connection {
  nodes: [Node]
}

type Story implements Node
@doc(description: "Story in the feed")
{
  id: ID!
  author: User
  editor: User
}

type User implements Node
@doc(description: "Story in the feed")
{
  id: ID!
  name: String
  stories: Connection @through(field: "author", ofType: "Story")
  username: String @deprecated(reason: "Use name instead")
}

type Query {
  story(id: ID!): Story
  user(id: ID!): User
}

We are experimenting with generating GraphQL.js schemas from the schema definition language and this syntax would provide a nice way add metadata to the types for that purpose.

I have implemented a proof of concept of this syntax in the schema parser, so I can also open a PR, if this is a good idea.

@schrockn-zz
Copy link
Contributor

This is a great idea and we definitely want to explore this. One issue is that we would want support for multi-line strings and markdown so we would need to think about how to incorporate that

@fson
Copy link
Contributor Author

fson commented Aug 10, 2015

@schrockn do you have some ideas how those multiline strings could look like?

The example I posted reuses the directive syntax from GraphQL documents. One option could be to keep that syntax, but let the arguments to be multiline strings (a new construct), e.g.:

type User {
  stories: StoryConnection
  @meta(
    description: "All stories authored by the user."
    examples: """
      Here are some examples written in markdown.

      You can use all the normal arguments.
      ```
      stories(first: $first) { nodes { text } }
      ```
      etc.
      """
    deprecationReason: "You should not use this anymore."
  )
}

Or used with separate directives for all these (argument names make this a bit noisy):

type User {
  stories: StoryConnection
  @description(text: "All stories authored by the user.")
  @examples(text: """
    Here are some examples written in markdown.

    You can use all the normal arguments.
    ```
    stories(first: $first) { nodes { text } }
    ```
    etc.
    """)
  @depracated(
    reason: "You should not use this anymore."
    sinceDate: "2015-08-11"
  )
}

I think the benefit of this approach is that it allows more information to be easily added in the later versions through new directives or new arguments for existing directives. It also borrows the syntax from queries, so there's no new syntax to be learned or implemented besides multiline strings.

@leebyron
Copy link
Contributor

The annotation syntax is a good idea. I definitely think descriptions should have the simplest possible syntax. We should treat those in a first-class way since they are so pervasive.

Maybe we should investigate doing something similar to literate coffeescript

@fson
Copy link
Contributor Author

fson commented Sep 19, 2015

I changed the syntax a bit to move the field directive before the field it applies to. I think this is more readable and also familiar from JS decorators, Java annotations etc.

There is now a pull request that implements directives for fields in type definitions: #180. Please let me know what you think.

@freiksenet
Copy link
Contributor

@schrockn, @leebyron: Ping?

@buchanae
Copy link

Might you consider putting annotations inside multi-line comments?

type User {
    """
    User documentation goes here. Easy to write __Markdown__ here?

    If someone wanted to extend the ability of comments, they could. Maybe a sort of doctest?
    """

    stories: StoriesConnection
    """
    Maybe you could associate this comment with a the stories field. Or should it come before?

    @deprecated: on 11-11-15 for whatever reason.
    """

    other: Int # These comments could stay associated too
}

Just an idea. Obviously inspired by Python.

@fson
Copy link
Contributor Author

fson commented Nov 15, 2015

@abuchanan Yeah, also look at @leebyron's suggestion using the existing single-line comments: #180 (comment). I think it could be a nice way to add them without introducing additional syntax.

I experimented a bit with adding annotations inside comments. The only problems were that the parser then needs to be made aware of comments everywhere (at the moment it discards them at the lexing stage), making parsing more complex, and distinguishing description comments from other comments. Parsing should be smart enough to handle cases like this:

# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.
# (This is not a description for Foo)

type Foo implements Bar {
  # Random note

  # Description for `name`
  name: String
}

Still, I think utilizing comments would probably be the simplest way to add annotations.

@sheerun
Copy link

sheerun commented Mar 25, 2016

Even if you want to use annotations instead of comments, please make sure one can read comments from parsed schema. Otherwise information is lost after parse -> print cycle.

@helfer
Copy link
Contributor

helfer commented May 4, 2016

@fson I just wrote up a related proposal for adding metadata to schemas here: https://github.com/apollostack/graphql-decorators/blob/master/README.md

It needs some more work, but it would be great to get your input. I'm hoping that if we all agree on something, a successful PR can be made.

@leebyron leebyron closed this as completed May 7, 2016
@leebyron
Copy link
Contributor

leebyron commented May 7, 2016

Committed in #382 - thanks for starting this!

@fson
Copy link
Contributor Author

fson commented May 7, 2016

Awesome, thanks! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants