Netflix / dgs-codegen

Apache License 2.0
182 stars 99 forks source link

feat: annotate kotlin input type to enable deserialization #684

Closed dwilkolek closed 4 months ago

dwilkolek commented 5 months ago

Motivation We are migrating from java to kotlin codegen types. We have few quite complex input types. In our test suite we deserialise JSON files and we validate them. We'd like to keep that functionality after migration as it really simplifies our test suite.

Generated input type before changes

public class TestInput(
    public val workspaceKey: String,
    public val name: String,
) : GraphQLInput() {
    override fun fields(): List<Pair<String, Any?>> = listOf("workspaceKey" to workspaceKey, "name" to
        name)
}

Test

@Test
fun `should deserialize`() {
    val json = """
        {
            "workspaceKey": "KEY",
            "name": "Damian"
        }
    """.trimIndent()
    ObjectMapper().readValue(json, TestInput::class.java)
}

Error during deserialization

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.TestInput` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{
    "workspaceKey": "KEY",
    "name": "Damian"
}"; line: 2, column: 5]

Generated input type after PR changes

public class TestInput @JsonCreator constructor(
    @JsonProperty("workspaceKey") 
    public val workspaceKey: String,
    @JsonProperty("name") 
    public val name: String,
 ) : GraphQLInput() {
    override fun fields(): List<Pair<String, Any?>> = listOf("workspaceKey" to workspaceKey, "name" to
        name)
}
srinivasankavitha commented 4 months ago

@mbossenbroek - could you please have a look when you get a chance?

mbossenbroek commented 4 months ago

LGTM - thanks for the addition @dwilkolek! Also feel free to tag me directly as a reviewer for any of the kotlin2 stuff; otherwise I don't watch this repo.