Skip to content

GraphQL schema language #3

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

Closed
dumbNickname opened this issue Nov 15, 2017 · 7 comments
Closed

GraphQL schema language #3

dumbNickname opened this issue Nov 15, 2017 · 7 comments

Comments

@dumbNickname
Copy link

Is it possible to use this module with GraphQL schema language? If so would it be possible to extend the docs o demonstrate such a usage? Thank you in advance :)

@ivome
Copy link
Collaborator

ivome commented Nov 18, 2017

Right now this is not possible and would have to be added. There are a few questions that would have to be solved, specifically how do you want to add a JS function that dynamically calculates the complexity based on input arguments via the GraphQL SDL? I am not sure if the SDL Document would be the best place for that... depending on the amount of logic in the complexity function this could quickly get out of hand.

I am open to ideas and adding support for something like that if we find a clean approach to add it.

@dumbNickname
Copy link
Author

dumbNickname commented Nov 21, 2017

Hey, I forgot that I raised this question, please excuse my late response. As I wanted to proceed with my experiments I made some research, went through your code and decided to use so called directives - it is an undocumented schema language part (found somewhere in github issues/discussions, but already used e.g. by apollo for cache control). What I ended up with is something like:

On type declaration:

type Query {
    hello:String @complexity(val:100)
}

some code that I added to consume directives declarations:

const complexityDirective = field.astNode
         .directives
         .filter(directive => directive.name.value === 'complexity')[0]; // or use find
   if (complexityDirective) {
        const valArg = complexityDirective.arguments
            .filter(arg => arg.name.value === 'val')[0]; // or use find
            if (valArg) {
                nodeComplexity = +valArg.value.value + childComplexity;
            }
   }

I hope it gives you the idea how it worked for me.

I am not sure if the SDL Document would be the best place for that... depending on the amount of logic in the complexity function this could quickly get out of hand.

I also do not know yet how "pure" and flexible is this approach but till now it works fine for me and allowed me to stick to schema language. I hope it helps you/this library in any way . If you would like to have a pull request then just let me know - I will try to deliver something.

Cheers

@GabrielDelepine
Copy link

Hi @dumbNickname

In this Github comment, @leebyron does not seem to recommend the custom directive approach.

@leebyron is saying that adding custom directive makes your Graphql Schema "not standard" which is not something desirable.

I still don't have my own opinion on this question. I just wanted to point it out.

@dumbNickname
Copy link
Author

Hi @GabrielDelepine

Thanks for your response. The comment pointed by you was one of hints I found when looking for a solution working with GraphQL SDL. This is also why I wrote it is an undocumented feature, which rises all the risks mentioned and possible compatibility problems. In general I thought any solution is better than no solution, but will not try to force anybody to pick it up. Anyway, thanks for pointing out those thoughts explicitly, now this thread is more complete.

@Piefayth
Copy link
Contributor

For anyone else with this problem, we circumvented it by modifying the "generated" schema directly. With a combination of getType and getFields you can get a reference to the individual fields within the schema, then simply add the complexity property to them.

@ptpaterson
Copy link

@GabrielDelepine, the linked comment regarding "adding custom directives", addresses custom Query directives, suggesting that providing clients with new directives has the potential to introduce new non-spec behavior. However, @dumbNickname is asking about Schema language directives. Does that sound like a fair assesment.

there is no change to the GraphQLSchema object and therefore also no changes to the introspection API.

So everything on the client side should still be expected spec-compliant behavior. But the server side has more direction to obtain and format results.

Graphcool does this with @relation and @index directives, for example. But they use the Scala implementation, and I am not sure how or at what point the directives get consumed.

@ivome
Copy link
Collaborator

ivome commented Sep 6, 2018

With the release of version 0.2.0 the new feature of configurable estimators was introduced. The directiveEstimator lets you configure the complexity and multipliers via GraphQL directives which can be set via schema definition language.

The solution described by @Piefayth can also be simplified since the estimator is passed the current type and field automatically. You could simply create a custom estimator and let it calculate the value in any way.

Estimators can also be combined now. We can set a default complexity and customize only certain fields via directive, field config etc.

@ivome ivome closed this as completed Sep 6, 2018
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

5 participants