apollo-kotlin
apollo-kotlin copied to clipboard
Java codegen: Add option to generate GraphQL enums as Java enums (opposite of Kotlin `sealedClassesForEnumsMatching`)
Summary
Enum declared in graphql schema is generated differently for Java and Kotlin changing with generateKotlinModels.set(false)
. Is this by design?
Version 3.3.2
Description
I would expect enum in schema generated as enum class
for Kotlin - done. Also as enum
for Java - now enum is generad as class with static fields.
Currently:
public class JobState {
public static EnumType type = new EnumType("JobState");
public static JobState RUNNING = new JobState("RUNNING");
public static JobState SUCCEEDED = new JobState("SUCCEEDED");
public static JobState FAILED = new JobState("FAILED");
public String rawValue;
//rest ommited
}
Hi 👋
The reason GraphQL enums are mapped to Java classes (and not Java enums) is to allow access to the rawValue
that is not known at compile time for new enum values. Imagine your backend introduces a new PAUSED
JobState. With a Java enum, the best we can do is map that to an UNKNOWN
enum. But that doesn't tell if it's PAUSED
or something else.
Now Kotlin has another parameter named sealedClassesForEnumsMatching
to opt-in that behaviour but it was never implemented for Java for lack of time. I can see how that's confusing when comparing both codegens. We can certainly add this option when focusing on the Java runtime but there's a lot on the todo list before we can tackle this topic. Feel free to send a pull request though if you're intereseted and we'll look into it!
I was mainly curious. For now it is not problem so I can live without it. For now. If it will became required I will create MR for sure. Thx for answer.
I've updated the title of this issue to make the expected outcome clearer. Let us know if you look into it. If not, we'll tackle this as part of the larger "Java Runtime" effort.
Hello, sorry for late response.
I will try to have a look. Will see if I can manage to do it :)
Thanks 💜
I'd suggest you look into the Kotlin Service.sealedClassesForEnumsMatching
. The main difference is that by default it should be listOf(".*")
as to not break the current behaviour. Maybe something like this?
/**
* A list of [Regex] patterns for GraphQL enums that should be generated as Java classes.
*
* Use this if you want your client to have access to the rawValue of the enum. This can be useful if new GraphQL enums are added but
* the client was compiled against an older schema that doesn't have knowledge of the new enums.
*
* Default: listOf(".*")
*/
val classesForEnumsMatching: ListProperty<String>
With #4404 the new option classesForEnumsMatching
has been added for this. This will be in the next release, in the meantime it can be tried out with the snapshots.
@BoD Is this ok to close? I saw it was closed on the project board.
@nateql This is done but has not been released yet - in that case we usually put the "Fixed in SNAPSHOTs" label but keep the issue open, until it's released. It will be part of 3.7.
@BoD ok, thank you for the explanation!
Available in 3.7.0