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

How to implement SchemaDirectiveVisitor like in Apollo? #748

Closed
fabis94 opened this issue Dec 3, 2020 · 2 comments
Closed

How to implement SchemaDirectiveVisitor like in Apollo? #748

fabis94 opened this issue Dec 3, 2020 · 2 comments
Labels

Comments

@fabis94
Copy link
Contributor

fabis94 commented Dec 3, 2020

I'm trying to implement directives similarly to how Apollo does it with the SchemaDirectiveVisitor class. Is this possible?

I'm trying a Type Config Decorator function to implement directives, because my schema is written in the GraphQL Type Language in a .graphql file. One issue I'm having is that I can't access schema definitions from this function (GraphQL\Type\Definition\Directive instances). I can only access directives as GraphQL\Language\AST\DirectiveNode instances - specific directive assignments to specific types. I need the actual Directive definition to be able to get the default value, for example.

It looks like if I'd build the entire schema using classes not with the Type Language I could access what I need, but that isn't an option, defining the schema in a .graphql file is a lot easier and less verbose.

Any suggestions on how to deal with this? Maybe you have suggestions on how to implement Directives similarly to how Apollo does it?

Secondary question:

I'm stitching together multiple .graphql files like this (this was suggested in another ticket):

    public function buildTypeDefsString(GraphQLApiConfig $config): string
    {
        $typeDefs = $config->getTypeDefFiles();

        /** @var ?Schema $schema */
        $schema = null;
        foreach ($typeDefs as $typeDef) {
            $typeDefContent = file_get_contents($typeDef);
            $documentNode = Parser::parse($typeDefContent);

            // Initialize schema or extend it
            $schema = $schema
                ? SchemaExtender::extend($schema, $documentNode)
                : BuildSchema::build($documentNode);
        }

        return BetterSchemaPrinter::doPrint($schema);
    }

So I do this first just to get the total combined schema, then I print it to a string and pass it into BuildSchema::build() to build it again, just so that I can attach a type config decorator. Seems inefficient - building the schema, serializing it to string and then building the schema from the string again.

Is there any way to adjust an existing schema with a type config decorator without this inefficiency?

@fabis94
Copy link
Contributor Author

fabis94 commented Dec 4, 2020

Also - why is the fields field of the $typeConfig passed into a type config decorator a callable? If it would have the same format as described in the docs (an array of field configs), then this decorator could be used to also change field description, customize field resolver etc. But currently it's a callable and calling it manually throws all sorts of errors. Any way to get around this?

@fabis94
Copy link
Contributor Author

fabis94 commented Dec 17, 2020

I managed to do this. Basically the SchemaDirectiveVisitor replaces the 'fields' callable with a new callable, that besides executing the original one, also does some extra things like changes field config.

Also I got around the schema combination issue by just manually extending the AST, it wasn't that difficult.

@fabis94 fabis94 closed this as completed Dec 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants