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

Default values not working for @GraphQLArgument in 0.9.8 #163

Closed
szantogab opened this issue Aug 20, 2018 · 11 comments
Closed

Default values not working for @GraphQLArgument in 0.9.8 #163

szantogab opened this issue Aug 20, 2018 · 11 comments

Comments

@szantogab
Copy link

HI!

Great release for 0.9.8, it was long awaited :)

One issue I encountered with 0.9.8 is that @GraphQLArgument seems to ignore defaultValue.

I have the following code:

    @GraphQLQuery(description = "Queries nearby ShoutOuts, that should be displayed on the map for the given user.")
    fun discoverShoutOuts(lat: Double, lng: Double, @GraphQLArgument(name = "radiusInMeters", defaultValue = "50000") radiusInMeters: Double): Collection<ShoutOut> = shoutOutService.discoverShoutOuts(lat, lng, radiusInMeters)

After upgrading to 0.9.8 the radiusInMeters argument is required and doesn't have a default value.

Is there anything to do with it to make it work?

I tried to debug it, and I see that in AnnotatedArgumentBuilder, the defaultValue() method correctly returns the value I specified, so the problem must be afterwards.

@kaqqao
Copy link
Member

kaqqao commented Aug 20, 2018

Ouch 😫
Will check it. If this is broken, 0.9.9 will have to come out immediately...

@szantogab
Copy link
Author

I'm glad to help you if you can point me to the class where it is likely broken.

@kaqqao
Copy link
Member

kaqqao commented Aug 20, 2018

A quick test in Java doesn't seem to replicate the issue for me:

@GraphQLQuery(description = "Queries nearby ShoutOuts, that should be displayed on the map for the given user.")
public Collection<String> discoverShoutOuts(Double lat, Double lng, @GraphQLArgument(name = "radiusInMeters", defaultValue = "50000") Double radiusInMeters) {
    return Collections.emptyList();
}

AnnotatedArgumentBuilder#defaultValue would indeed be my first suspect. If that's fine, could you maybe break at OperationMapper#toGraphQLArgument and check what happens there? Same for DefaultOperationBuilder.java:106?

@szantogab
Copy link
Author

After digging deeper, it seems like when I execute a GraphQL request with the value not specified, it works fine and it uses the default value. However, GraphiQL shows me an error that a required argument is not specified.

Looking at the introspection query response, it seems like the defaultValue is there, but the field is NON_NULL:

{"name":"radiusInMeters","description":"","type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Float","ofType":null}},"defaultValue":"50000.0"}

So I can't tell it it's a bug or it is supposed to be like this.

@szantogab
Copy link
Author

szantogab commented Aug 20, 2018

I checked the code at OperationMapper#toGraphQLArgument and it seemed fine, except that the type was GraphQLNonNull, which I think is wrong, but please correct me if this is not how it's working :)

@kaqqao
Copy link
Member

kaqqao commented Aug 20, 2018

In 0.9.8, primitives are always non-null, and I unfortunately don't know enough Kotlin to say what is primitive and what isn't 😕
Could you perhaps break at NonNullMapper#supports and check if that specific argument is detected as primitive?
That would explain the non-nullness.

@kaqqao
Copy link
Member

kaqqao commented Aug 20, 2018

Also, it might be worth to try the latest version of GraphiQL, as it sounds like a possible bug in there... but I'm not sure how to interpret this behavior yet.

@szantogab
Copy link
Author

szantogab commented Aug 20, 2018

Yes, it is recognized as a primitive. If I make a type nullable in Kotlin, for example: Int?, that's when it is represented as Integer in Java.

So going back to the previous example:

    @GraphQLQuery(description = "Queries nearby ShoutOuts, that should be displayed on the map for the given user.")
    fun discoverShoutOuts(lat: Double, lng: Double, @GraphQLArgument(name = "radiusInMeters", defaultValue = "50000") radiusInMeters: Double): Collection<ShoutOut> = shoutOutService.discoverShoutOuts(lat, lng, radiusInMeters)

It is clear that radiusInMeters is a double primitive and it's non-nullable, and that's exactly what I want in the CODE. But since a defaultValue is provided, it is not required to specify this argument.

Conclusion: is it possible to make arguments that have a default value nullable in the schema? I guess it would make sense?!

Thanks :)

@kaqqao
Copy link
Member

kaqqao commented Aug 21, 2018

I remembered having a reason to leave primitives alone, but I forgot what it was and making them non-null seemed logical... Now the reason is apparent.
For the moment, I'd say either use the non-primitive double or replace the NonNullMapper (just extend it and override the supports method), and I'll release 0.9.9 with a fix this weekend.

To replace a mapper:

generator.withTypeMappers((conf, current) -> current.replace(NonNullMapper.class, new CustomNonNullMapper()))

@kaqqao kaqqao closed this as completed in ad27b1d Aug 29, 2018
@kaqqao
Copy link
Member

kaqqao commented Sep 5, 2018

The GraphQL spec has changed to better deal with non-null arguments with a default value.
graphql/graphql-spec#418
Not sure if/when this will take effect in graphql-java.

@kaqqao
Copy link
Member

kaqqao commented Sep 5, 2018

My commit makes sure everything with a default value is nullable, so that will be the behavior in 0.9.9.

When graphql-java catches up with the spec, I'll probably have to revert that bit.

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