leangen / graphql-spqr

Build a GraphQL service in seconds
Apache License 2.0
1.09k stars 179 forks source link

Kotlin isX field is excluded on input types #465

Closed IceBlizz6 closed 12 months ago

IceBlizz6 commented 12 months ago

In Kotlin i have this class

class PostUpdate(
    val isDelivered: Boolean
)

Using javap then i see that this is equivalent to:

public class PostUpdate {
  private final boolean isDelivered;
  public PostUpdate(boolean);
  public final boolean isDelivered();
}

Trying to set up this as a unit test:

public class PostUpdate {
    private final boolean isDelivered;

    public PostUpdate(boolean isDelivered) {
        this.isDelivered = isDelivered;
    }

    public boolean isDelivered() {
        return isDelivered;
    }
}

public class PostService {
    @GraphQLQuery
    public void update(int id, PostUpdate input) {
        throw new RuntimeException("Not implemented");
    }
}

@Test
public void updatePostTest() {
    new GraphQLSchemaGenerator()
            .withOperationsFromSingleton(new PostService())
            .generateExecutable();
}

this unit test then fails:

graphql.schema.validation.InvalidSchemaException: invalid schema: "PostUpdateInput" must define one or more fields.

at graphql.schema.GraphQLSchema$Builder.validateSchema(GraphQLSchema.java:945) at graphql.schema.GraphQLSchema$Builder.buildImpl(GraphQLSchema.java:939) at graphql.schema.GraphQLSchema$Builder.build(GraphQLSchema.java:904) at io.leangen.graphql.GraphQLSchemaGenerator.generateExecutable(GraphQLSchemaGenerator.java:993) at io.leangen.graphql.BatchingTest.updatePostTest(BatchingTest.java:50)

Renaming isDelivered field to delivered will pass the unit test. However this is not a working solution because my code was generated from kotlin.

I can understand that it is unfortunate that Kotlin does not follow boolean naming convention in this regard. Sadly i have a lot of classes like this in my Kotlin project, most of these are auto generated. Would it be possible to solve this?

kaqqao commented 12 months ago

EDIT: Everything I said here was completely off topic, so I removed it not to confuse future readers.

IceBlizz6 commented 12 months ago

Looks like adding jackson-module-kotlin solved this issue. I like your idea of having a kotlin module for spqr. I may be able to contribute something. Right now i have:

Maybe we should continue this in a new discussion as i think this specific issue has been solved.

kaqqao commented 12 months ago

Ooh, sorry, I was completely off. All I said was about output types, and you were talking about input types. Yes, SPQR delegates the discovery of input fields to Jackson (or Gson, kind of). This way it avoids the insidious problem of everything seeming ok in the schema but failing to deserialize at runtime. Most Jackson configs should thus transparently work. So if you add the Jackson Kotlin module, making Jackson aware of Kotlin's quirky accessor naming, it should just start working in SPQR too, yeah.

And yes, let's continue the Kotlin SPQR module discussion elsewhere.