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

Generate schema with directive at field #90

Closed
hspedro opened this issue May 13, 2020 · 2 comments
Closed

Generate schema with directive at field #90

hspedro opened this issue May 13, 2020 · 2 comments

Comments

@hspedro
Copy link

hspedro commented May 13, 2020

Feature requests

Hi all, I'm trying to generate a schema that has a directive at a field:

directive @hasPermissions(permissions: [String]) on OBJECT | FIELD_DEFINITION

type MyType {
  field1: Boolean @hasPermissions(permissions: ['permission1', 'permission2'])
}

type Query {
  myType: MyType
}

However, I did not found a way to generate this using the library. For instance, I tried defining the directives attribute from GraphQLField.ast_node but print_schema did not generated field with the directive:

from graphql.language import (
    FieldDefinitionNode, DirectiveLocation, DirectiveNode, ArgumentNode
)
from graphql.type import (
    GraphQLArgument,
    GraphQLBoolean,
    GraphQLDirective,
    GraphQLField,
    GraphQLList,
    GraphQLObjectType,
    GraphQLSchema,
    GraphQLString,
)
from graphql.utilities import print_schema

if __name__ == "__main__":
    MyType = GraphQLObjectType(
        "MyType",
        lambda: {
            "field1": GraphQLField(
                GraphQLBoolean,
                ast_node=FieldDefinitionNode(
                    directives=[DirectiveNode(
                        name="hasPermissions",
                        arguments=[
                            ArgumentNode(
                                name="permissions",
                                value=["permission1", "permission2"]
                            )
                        ]
                    )]
                )
            ),
        },
    )

    MyTypeQuery = GraphQLObjectType(
        "Query",
        {
            "myType": GraphQLField(MyType),
        },
    )
    schema = GraphQLSchema(
        directives=[GraphQLDirective(
            name="hasPermissions",
            locations=[
                DirectiveLocation.OBJECT,
                DirectiveLocation.FIELD_DEFINITION
            ],
            args={
                "permissions": GraphQLArgument(GraphQLList(GraphQLString)),
            },
        )],
        query=MyTypeQuery,
    )
    print(print_schema(schema))

Output:

directive @hasPermissions(permissions: [String]) on OBJECT | FIELD_DEFINITION

type Query {
  myType: MyType
}

type MyType {
  field1: Boolean
}

Is there any way to generate a schema with directive at the field declaration? If not, I can contribute on that.

@hspedro
Copy link
Author

hspedro commented May 13, 2020

As I was debugging, I saw that print_field from print_schema.py only writes the directive for @deprecated. Could it be the case of adding something to recursively parse ast_node.directives and add to print_fields? https://github.com/graphql-python/graphql-core/blob/master/src/graphql/utilities/print_schema.py#L197

@Cito
Copy link
Member

Cito commented May 13, 2020

Currently, you can add custom directives only via SDL, like this:

schema = build_schema("""
directive @hasPermissions(permissions: [String]) on OBJECT | FIELD_DEFINITION

type MyType {
  field1: Boolean @hasPermissions(permissions: ["permission1", "permission2"])
}

type Query {
  myType: MyType
}
""")

Arguably, this is also the only case where such directives are needed. On your hand-made object types, you can simply use a hasPermissions function in your resolvers instead of using directives.

There are long discussions about this in JavaScript land e.g. here and here.

The goal of graphql-core is to be a 1:1 port of GraphQL.js. If you have good reasons to add a feature, you can advocate this to the GraphQL.js folks which have great expertise and experience. If they agree it makes sense, it will be eventually implemented there and then ported over here.

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

2 participants