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

Enum values with a custom name cannot be serialized when returning from a query or mutation

Open dconard opened this issue 3 years ago • 1 comments

Library Version 6.0.0

Describe the bug I'm using @GraphQLName and @JsonProperty annotations to change the name of some enum values in our graphql schema. The generated schema is correct, and reflects the overridden names. However, when I try to call a query or mutation that will return the enum, the entire query fails due to invalid serialization. It seems that the JsonProperty values are not being respected when the enum is supposed to be returned from a query or mutation.

To Reproduce

This is an example enum I've been attempting to use:

enum class MyCustomEnum {
    @GraphQLName("firstOption")
    @JsonProperty("firstOption")
    OPTION_A,

    @GraphQLName("secondOption")
    @JsonProperty("secondOption")
    OPTION_B,

    @GraphQLName("thirdOption")
    @JsonProperty("thirdOption")
    OPTION_C,
}

And this is an example of a query:

class MyQuery {
    fun getAllValues() : List<MyCustomEnum> {
        return MyCustomEnum.values().toList()
    }
}

Expected behavior The schema generated is correct. It returns something like this:

enum MyCustomEnum {
  firstOption
  secondOption
  thirdOption
}

The issue comes up when I try to actually call the generated graphql query. I end up with 3 exceptions (one for each enum value) saying that the enum value cannot be serialized:

graphql.schema.CoercingSerializeException: Invalid input for Enum 'MyCustomEnum'. Unknown value 'OPTION_A'
	at graphql.schema.GraphQLEnumType.getNameByValue(GraphQLEnumType.java:155)
	at graphql.schema.GraphQLEnumType.serialize(GraphQLEnumType.java:71)
	at graphql.execution.ExecutionStrategy.completeValueForEnum(ExecutionStrategy.java:621)
	at graphql.execution.ExecutionStrategy.completeValue(ExecutionStrategy.java:444)
	at graphql.execution.ExecutionStrategy.completeValueForList(ExecutionStrategy.java:546)
	at graphql.execution.ExecutionStrategy.completeValueForList(ExecutionStrategy.java:500)
	at graphql.execution.ExecutionStrategy.completeValue(ExecutionStrategy.java:439)
	at graphql.execution.ExecutionStrategy.completeField(ExecutionStrategy.java:404)
        ...

I've noticed that once the graphql.schema.GraphQLEnumType#getNameByValue(Object value) method is called, the value is OPTION_A instead of firstOption. I'm unsure why the serialization value isn't respecting the JsonProperty annotations.

dconard avatar Jul 29 '22 22:07 dconard

After update from v5.5.0 to v6.1.0 i have a similar problem:

I use an enum as a parameter for my query:

@GraphQLName("sortOrder")
@GraphQLDescription("Possible sort orders")
enum class SortingOrder {
    @JsonProperty("asc")
    @GraphQLName("asc")
    ASCENDING,

    @JsonProperty("desc")
    @GraphQLName("desc")
    DESCENDING
}

If i try to use this parameter in my query:

query myQuery {
  myQuery( sortOrder: asc) {
	name
  }
}

i get the following error:

WARN  [2022-08-04 13:11:34,687] notprivacysafe.graphql.execution.SimpleDataFetcherExceptionHandler: Exception while fetching data (/myQuery) : Collection contains no element matching the predicate.
! java.util.NoSuchElementException: Collection contains no element matching the predicate.
! at com.expediagroup.graphql.generator.execution.ConvertArgumentValueKt.mapToEnumValue(convertArgumentValue.kt:123)
! at com.expediagroup.graphql.generator.execution.ConvertArgumentValueKt.convertValue(convertArgumentValue.kt:78)
! at com.expediagroup.graphql.generator.execution.ConvertArgumentValueKt.convertArgumentValue(convertArgumentValue.kt:51)
! at com.expediagroup.graphql.generator.execution.FunctionDataFetcher.mapParameterToValue(FunctionDataFetcher.kt:101)
! at com.expediagroup.graphql.generator.execution.FunctionDataFetcher.getParameters(FunctionDataFetcher.kt:79)
! at com.expediagroup.graphql.generator.execution.FunctionDataFetcher.get(FunctionDataFetcher.kt:58)
! at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:282)
! at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:211)
! at graphql.execution.AsyncExecutionStrategy.execute(AsyncExecutionStrategy.java:59)
! at graphql.execution.Execution.executeOperation(Execution.java:159)
! at graphql.execution.Execution.execute(Execution.java:105)
! at graphql.GraphQL.execute(GraphQL.java:643)
! at graphql.GraphQL.lambda$parseValidateAndExecute$11(GraphQL.java:563)
...

If i do not use the @GraphQLName directive in the enum class the query can be used with the original enum Value ASCENDING instead of asc without an exception

dig-leanix avatar Aug 04 '22 13:08 dig-leanix