You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Validation directives on nested Input fields example #385
I would think implementation of the onInputObjectField callback would be similar to the samples of onArgument and onField. Isn't it possible to deduce it from those samples?
Hi @oliemansm . I have tried to use the onField example but I am getting the error: Caused by: graphql.AssertException: An output field must be in context to call this method on calling
Yeah not working for me too.
We are using kickstart with java extended validations library.
The library works but then resolvers dont.
And if resolvers work then validation wont.
@sumitbadaya27 You're issue seems to be different than what @PhilippS93 raised. You're not getting the validators from that library to work with this project apparently. I don't know how you configured it, but they don't provide a starter but just a library. So you have to expose their SchemaDirectiveWiring into a SchemaDirective bean to be actually configured.
@PhilippS93 graphql-java hasn't documented this either and they refer to https://github.com/graphql-java/graphql-java-extended-validation for example implementation. It uses a FieldDefinition and walks the arguments and input types based on that. I'll see if I can get something like that to work in the sample.
@oliemansm Is there any way through in your library in which we can pass typeDefinitionRegistry and runtimeWiring in generating schema in schemaParser builder?
basically this thing: GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);
Also, I configured it correctly as I am getting proper validation message but its just that I am not able to add resolvers and my resolvers fail to work if Validation works.
The problem is that graphql-java-tools wires the directive on objects and its fields without passing along the constructed GraphQLInputObjectType. That's what is preventing that extended-validation library to fail too. Because it does an instanceof check in case the argument is a GraphQLInputObjectType, while in fact at that point because of the logic in graphql-java-tools, it is a GraphQLTypeReference.
By making some quick changes in graphql-java-tools I was able to pass it along and got it working. Needs a bit more work and clean-up though.
Till the time you cleanup the code, Can you please provide the code that
you tweaked ans tried and the location where i need to put that code?
So that my work also doesnt stop at this as i am blocked coz of this
In recent versions base packages have been migrated as stated in the release notes. Remove the imports and your IDE should already help you importing the correct versions (graphql.kickstart based packages).
No you don't include graphql-java-tools directly. Rely on graphql-spring-boot-starter to import graphql-java-tools. In the POM you've described above you're importing GraphiQL, not graphql-spring-boot-starter.
Come on, just read.... This is costing me a lot of time that's totally unnecessary. I said to use version 7.0.2-SNAPSHOT of graphql-spring-boot-starter and you're clearly using 7.0.1. Don't pull in graphql-java either, that's done for you by graphql-spring-boot-starter too.
Then try to add the graphql-java dependency anyway. You should start trying to investigate, debug and figure out why certain errors pop-up instead of asking questions each time you run into something. Programming isn't copy pasting code around until something just magically works. It's about understanding how and why something works and applying that. In the end and also in this case you'll only get that kind of understanding by following the code.
If everything else in this library is working as it should and the problem with that type not being found is limited to your use case and configuration then there's no reason to assume it'll be solved by a next release. Might just be caused by that library you're trying to use.
I'm not using directives on input objects, and I'm not using that extended validator directive library either. And I'm not getting paid for the time I put in this project, so there's no incentive whatsoever for me to put in these hours in my free weekend. I'm going to limit my time now to just fixing this original input validation example, and not to the support of that library. If you keep running into problems with that library icw this library then I suggest you figure out the cause and if it's related to a bug or something in this project create a PR to fix it.
I have figured it out already and fixed it. Was about to post message but was afraid you'd not like it to see another message .
thanks for the fixes and support till now.
Thanks @brendamckenne. You might as well delete that graphql-java-tools from your POM entirely btw and just let graphql-spring-boot-starter handle that dependency. That prevents compatibility issues that might otherwise easily occur. We try to update graphql-spring-boot-starter in sync with graphql-java-tools.
@PhilippS93 Back to your original question. I've updated the sample (not the documentation). Take a look at this RangeDirective. It works on both a regular argument and input object. The solution is based on graphql-java-extended-validation from the guys that develop graphql-java, the library that provides the directive implementation in the first place.
Documentation on their end is lacking too for this particular use case. Basically how it works is you don't override the onArgument or onInputObjectField methods, but you override the onField method. Then you iterate over the arguments of that field checking if your directive applies or not. You need to walk up over input object types as well in that case and take lists into account if you need to (this sample doesn't do that btw).
Basically you need to write quite a bit of code to get the result of what you'd want. That's because graphql-java provides an API trying to give you us much flexibility as possible, but in this case making it a bit more difficult to work with.
Perhaps it would be possible to come up with an interface in graphql-spring-boot-starter to simplify it.
My example code doesn't traverse all the way up into nested input objects, so you'd have to add that kind of logic to be able to get that working. As I've indicated above it isn't the most developer friendly solution and some kind of convenience interface for this would come in handy to make it easier to work with.
I'll reopen the issue and rename it for nested input directives.
Activity
oliemansm commentedon Feb 12, 2020
Hi,
I would think implementation of the
onInputObjectFieldcallback would be similar to the samples ofonArgumentandonField. Isn't it possible to deduce it from those samples?PhilippS93 commentedon Feb 12, 2020
Hi @oliemansm . I have tried to use the onField example but I am getting the error:
Caused by: graphql.AssertException: An output field must be in context to call this methodon callingbrendamckenne commentedon Apr 3, 2020
did you get this resolved anyhow? @PhilippS93
mohammali commentedon Apr 3, 2020
Any update?
PhilippS93 commentedon Apr 4, 2020
@sumitbadaya27 , no the provided examples are unfortunately not working. @oliemansm , any ideas?
brendamckenne commentedon Apr 4, 2020
oliemansm commentedon Apr 4, 2020
I’ll try to take a look at it this weekend.
brendamckenne commentedon Apr 4, 2020
Thanks
In case you'd need the link of library for validations, Its here:
https://github.com/graphql-java/graphql-java-extended-validation
oliemansm commentedon Apr 4, 2020
@sumitbadaya27 You're issue seems to be different than what @PhilippS93 raised. You're not getting the validators from that library to work with this project apparently. I don't know how you configured it, but they don't provide a starter but just a library. So you have to expose their SchemaDirectiveWiring into a SchemaDirective bean to be actually configured.
@PhilippS93 graphql-java hasn't documented this either and they refer to https://github.com/graphql-java/graphql-java-extended-validation for example implementation. It uses a FieldDefinition and walks the arguments and input types based on that. I'll see if I can get something like that to work in the sample.
brendamckenne commentedon Apr 4, 2020
@oliemansm Is there any way through in your library in which we can pass typeDefinitionRegistry and runtimeWiring in generating schema in schemaParser builder?
basically this thing: GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);
Also, I configured it correctly as I am getting proper validation message but its just that I am not able to add resolvers and my resolvers fail to work if Validation works.
oliemansm commentedon Apr 4, 2020
@sumitbadaya27 Create a separate issue for that please, this particular issue is not about that library or these questions.
brendamckenne commentedon Apr 4, 2020
okay
oliemansm commentedon Apr 4, 2020
The problem is that graphql-java-tools wires the directive on objects and its fields without passing along the constructed
GraphQLInputObjectType. That's what is preventing that extended-validation library to fail too. Because it does an instanceof check in case the argument is aGraphQLInputObjectType, while in fact at that point because of the logic in graphql-java-tools, it is aGraphQLTypeReference.By making some quick changes in graphql-java-tools I was able to pass it along and got it working. Needs a bit more work and clean-up though.
brendamckenne commentedon Apr 4, 2020
oliemansm commentedon Apr 4, 2020
I'll push a snapshot release of graphql-java-tools when it's ready to do so and push the updated samples containing the example code then too.
You can do validation on the resolvers themselves in the meantime. That's a valid workaround available to you, so you're actually not blocked by this.
7 remaining items
oliemansm commentedon Apr 5, 2020
In recent versions base packages have been migrated as stated in the release notes. Remove the imports and your IDE should already help you importing the correct versions (graphql.kickstart based packages).
No you don't include graphql-java-tools directly. Rely on graphql-spring-boot-starter to import graphql-java-tools. In the POM you've described above you're importing GraphiQL, not graphql-spring-boot-starter.
oliemansm commentedon Apr 5, 2020
Come on, just read.... This is costing me a lot of time that's totally unnecessary. I said to use version 7.0.2-SNAPSHOT of graphql-spring-boot-starter and you're clearly using 7.0.1. Don't pull in graphql-java either, that's done for you by graphql-spring-boot-starter too.
brendamckenne commentedon Apr 5, 2020
ty
confusion was created by the link you shared ": https://github.com/graphql-java-kickstart/graphql-spring-boot#snapshots"
It has 7.0.1 snapshot version so I got confused by it.
oliemansm commentedon Apr 5, 2020
Then try to add the graphql-java dependency anyway. You should start trying to investigate, debug and figure out why certain errors pop-up instead of asking questions each time you run into something. Programming isn't copy pasting code around until something just magically works. It's about understanding how and why something works and applying that. In the end and also in this case you'll only get that kind of understanding by following the code.
If everything else in this library is working as it should and the problem with that type not being found is limited to your use case and configuration then there's no reason to assume it'll be solved by a next release. Might just be caused by that library you're trying to use.
I'm not using directives on input objects, and I'm not using that extended validator directive library either. And I'm not getting paid for the time I put in this project, so there's no incentive whatsoever for me to put in these hours in my free weekend. I'm going to limit my time now to just fixing this original input validation example, and not to the support of that library. If you keep running into problems with that library icw this library then I suggest you figure out the cause and if it's related to a bug or something in this project create a PR to fix it.
brendamckenne commentedon Apr 5, 2020
I have figured it out already and fixed it. Was about to post message but was afraid you'd not like it to see another message .
thanks for the fixes and support till now.
oliemansm commentedon Apr 5, 2020
Can you leave the cause and solution here in a comment then so anybody else that runs into the same problem you ran into will know how to solve it?
oliemansm commentedon Apr 5, 2020
Thanks @brendamckenne. You might as well delete that graphql-java-tools from your POM entirely btw and just let graphql-spring-boot-starter handle that dependency. That prevents compatibility issues that might otherwise easily occur. We try to update graphql-spring-boot-starter in sync with graphql-java-tools.
oliemansm commentedon Apr 5, 2020
@PhilippS93 Back to your original question. I've updated the sample (not the documentation). Take a look at this RangeDirective. It works on both a regular argument and input object. The solution is based on graphql-java-extended-validation from the guys that develop graphql-java, the library that provides the directive implementation in the first place.
Documentation on their end is lacking too for this particular use case. Basically how it works is you don't override the
onArgumentoronInputObjectFieldmethods, but you override theonFieldmethod. Then you iterate over the arguments of that field checking if your directive applies or not. You need to walk up over input object types as well in that case and take lists into account if you need to (this sample doesn't do that btw).Basically you need to write quite a bit of code to get the result of what you'd want. That's because graphql-java provides an API trying to give you us much flexibility as possible, but in this case making it a bit more difficult to work with.
Perhaps it would be possible to come up with an interface in graphql-spring-boot-starter to simplify it.
PhilippS93 commentedon Apr 16, 2020
Thank you @oliemansm . I have tested the new code but unfortunately it does not work for my case (see below for an example):
It seems that only ChangeUserInput is considered in the onField method, but not NameInput.
oliemansm commentedon Apr 17, 2020
My example code doesn't traverse all the way up into nested input objects, so you'd have to add that kind of logic to be able to get that working. As I've indicated above it isn't the most developer friendly solution and some kind of convenience interface for this would come in handy to make it easier to work with.
I'll reopen the issue and rename it for nested input directives.
[-]Input Validation example[/-][+]Validation directives on nested Input fields example[/+]dnagarajan89 commentedon Dec 19, 2020
@oliemansm I tried using the range directive logic for an InputObjectType like this.
type Mutation {
addBook(bookInput: BookInput!) : Book!
}
input BookInput {
id: Int! @range(minimum: 4, maximum:10)
name: String!
}
As I have used non null('!') for InputObjectType in the mutation, while unwrapping the non-null I am getting a GraphQLTypeReference instead of GraphQLInputObjectType in this LOC https://github.com/graphql-java-kickstart/samples/blob/master/directives/src/main/java/directives/RangeDirective.java#L38. Is there a way to get the GraphQLInputObjectType from GraphQLTypeReference to navigate the fieldDefinitions and look for directive ?
If I use the mutation parameter without non null, the logic is working fine.
addBook(bookInput: BookInput)
Please let me know if there is a way around.