micronaut-graphql icon indicating copy to clipboard operation
micronaut-graphql copied to clipboard

GraphQL fields are always null

Open patrickdronk opened this issue 3 years ago • 5 comments

Expected Behavior

When doing a simple query like

query {
  allBooks {
    name
  }
}

I would expect the name attribute to not be null.

Actual Behaviour

The query results in

{
  "data": {
    "allBooks": [
      {
        "name": null
      },
      {
        "name": null
      },
      {
        "name": null
      }
    ]
  }
}

Steps To Reproduce

please see the github repo.

Environment Information

No response

Example Application

https://github.com/patrickdronk/mn-graphql-graalvm-lambda

Version

3.3.0

patrickdronk avatar Mar 25 '22 23:03 patrickdronk

@patrickdronk is this a GraalVM issue?

sdelamo avatar Apr 19 '22 08:04 sdelamo

@sdelamo I would expect it to be. But I'm not sure. When I run it locally with tests, everything seems to be fine.

patrickdronk avatar May 02 '22 14:05 patrickdronk

I have the same problem when I convert my application to nativeImage, you can reproduce generating the native image of the guide CREATING A TODO APPLICATION WITH MICRONAUT GRAPHQL

ralmeida7 avatar Jun 10 '22 23:06 ralmeida7

Same problem here.

It is related to processing of @JsonAnyGetter annotation of class GraphQLResponseBody.java. For some reason properties of specification map are handled using reflection instead of bean introspection. You can fix issue by annotating returned objects with @ReflectiveAccess annotation.

Here another sample application of issue https://github.com/jmpalomar/micronaut-graphql-native-image-issue

I think a custom serializer for GraphQLResponseBody could fix the issue while the core team fixes bean introspection module to properly handle @JsonAnyGetter when native image.

UPDATE I did some more testing and seems there is something probably related to GraphQL using reflection itself.

When using JVM you get this output from GraphQLResponseBody:

08:04:25.625 [graphql-executor-thread-1] DEBUG io.energiaplus.shared.graphql.jackson.GraphqlResponseBodySerializer - Serializing GraphQLResponseBody: {data={customer={customerId=ec5d2d44-84c2-4bd1-8e00-2844a0af50ed, firstName=Luke, lastName=Skywalker, dob=1977-05-25, personalId={id=1Y, type=NIF}, [email protected], phone=611622633, addresses=[{address=Lars Farm, city=Mos Eisle, province=Mos Eisle, zipCode=41001, country=Tatooine}]}}}

When using native-image you get this instead:

08:13:18.836 [graphql-executor-thread-1] DEBUG io.energiaplus.shared.graphql.jackson.GraphqlResponseBodySerializer - Serializing GraphQLResponseBody: {data={customer={customerId=null, firstName=null, lastName=null, dob=null, personalId=null, email=null, phone=null, addresses=null}}}

It seems to me real issue is related to PropertyDataFetcher which uses reflection for retrieving properties. Solution should be replace PropertyDataFetcher by an alternative property data fetcher that uses bean introspection.

UPDATE 2 I can confirm issue is due PropertyDataFetcher using reflection and providing a property data fetcher that uses bean introspection or annotating all returned classes with @ReflectiveAccess will solve issue. And has nothing to do with @JsonAnyGetter.

jmpalomar avatar Mar 01 '24 06:03 jmpalomar

@msupic can you look into this?

sdelamo avatar Mar 07 '24 15:03 sdelamo