I've tried looking at the documentation to figure out how to accomplish this but got no where.
How do I define a schema like this using Graphene?
directive @unique(
info: String = "Blah blah"
) on FIELD_DEFINITION | ENUM_VALUE
directive @ignore(
info: String = Blah blah"
) on OBJECT
type ExampleType @ignore(info: "Blah"){
newField: String
oldField: String @unique(info: "Blah")
}
@prashanthellina it's not documented but you can pass directives when you create your schema:
from graphql.types.directives import specified_directives # <== default directives
from graphene import Schema
schema = Schema(query=Query, directives=specified_directives + [MyDirective])
You'll have to define your own directives but you can see how the @skip and @include and defined here: https://github.com/graphql-python/graphql-core/blob/8f7c8f3351dd0a4580b87f293aed7bfcf9126bc4/graphql/type/directives.py#L69-L98
Thank you @jkimbo for the example above. I can understand how this will help in accomplishing this part of the schema.
directive @unique(
info: String = "Blah blah"
) on FIELD_DEFINITION | ENUM_VALUE
directive @ignore(
info: String = Blah blah"
) on OBJECT
What do I do to get this part:
type ExampleType @ignore(info: "Blah"){
newField: String
oldField: String @unique(info: "Blah")
}
i.e. Telling Graphene to apply the custom directives I defined, at a field / object / enum level.
I _believe_ decorating on the Query would be supported by the resolver argument info. You can get the arguments from the resolve info parameter:
https://docs.graphene-python.org/en/latest/api/#execution-metadata
You'd have to write your logic in a decorating function or in the resolver itself.
I don't think that there is currently support for applying decorators on Schema, but you can definitely emulate the desired behavior through a wrapping class (kind of like List and NonNull in graphene). I'd love to dig into this a bit more though!
Here's an example of how directives are implemented in graphql-tools for Js.
https://www.apollographql.com/docs/graphql-tools/schema-directives/
@prashanthellina thanks for your patience. So I've looked into this a bit more and it looks like it's not possible to apply directives on a field/object level. This is a conscious limitation of the reference GraphQL server implementation graphql-js. You can read more about the reasoning here: https://github.com/graphql/graphql-js/pull/746#issuecomment-301554231 and follow the ongoing discussion about it here: https://github.com/graphql/graphql-js/issues/1343
The relevant comments from leebyron are:
Right now directives are purely a feature of the GraphQL language and IDL, so a schema not created using IDL definitionally won't contain directives. When building a schema in code, you have the full power of the host programming environment, so directives shouldn't be necessary. Directives are a tool for supplying additional intent to be later interpreted by the host programming environment.
and
Directives are purely a feature of the GraphQL language and are not part of type definitions - this is because different tools will use and interpret directives in different ways.
(there is also a great long comment which explains things in detail)
Since Graphene is based on graphql-core which is a direct port of the graphql-js implementation, support for directives on fields/objects won't happen until that support is available in graphql-js.
I hope that's helpful. You might also want to checkout ariadne which is an alternative way of building a GraphQL server using the SDL.
I'm going to create an new issue to document adding custom directives to the schema and then close this one.
@jkimbo Thank you for the confirmation. I thought I was missing something. I believe there is merit in implementing directives as I find that a good way to signal behavior formally (rather than in comments) to both the user of the schema/service and the implementer of the resolver logic.
I quite liked the way that prisma (https://www.prisma.io/) uses directives to provide more expressiveness when using the SDL to describe ORM like interactions with a database.
For the moment, I am exploring using GraphQLS2S for defining the schema in an SDL superset (that support inheritance, generics etc to help reduce verbosity) and then transpiling it to standard SDL. After I have the final schema, I am using ariadne to implement the actual resolver logic.
Most helpful comment
@jkimbo Thank you for the confirmation. I thought I was missing something. I believe there is merit in implementing
directivesas I find that a good way to signal behavior formally (rather than in comments) to both the user of the schema/service and the implementer of the resolver logic.I quite liked the way that
prisma(https://www.prisma.io/) uses directives to provide more expressiveness when using the SDL to describe ORM like interactions with a database.For the moment, I am exploring using GraphQLS2S for defining the schema in an SDL superset (that support inheritance, generics etc to help reduce verbosity) and then transpiling it to standard SDL. After I have the final schema, I am using
ariadneto implement the actual resolver logic.