micronaut-projects / micronaut-graphql

A repository for Micronaut and GraphQL integrations
Apache License 2.0
81 stars 43 forks source link

GraphQL fields are always null #253

Open patrickdronk opened 2 years ago

patrickdronk commented 2 years ago

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

sdelamo commented 2 years ago

@patrickdronk is this a GraalVM issue?

patrickdronk commented 2 years ago

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

ralmeida7 commented 2 years ago

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

jmpalomar commented 6 months ago

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=luke.skywaler@example.com, 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.

sdelamo commented 6 months ago

@msupic can you look into this?