Skip to content

Commit 60879c5

Browse files
authored
feat(client): update jackson client generation to always annotate all fields (#1976)
### 📝 Description Update Jackson client generation logic to always annotate all fields with @get:JsonProperty. This is a workaround to Jackson limitations due to its reliance on reflections to find getters/setters following JavaBean naming conventions. Simple mutation: ``` graphql mutation CreateIssuedInvoice($input: IssuedInvoiceInput!) { CreateIssuedInvoice(IssuedInvoice: $input) { ID Stav CisloDokladu } } ``` Genarated before change: ```kotlin public const val CREATE_ISSUED_INVOICE: String = "mutation CreateIssuedInvoice(${'$'}input: IssuedInvoiceInput!) {\n CreateIssuedInvoice(IssuedInvoice: ${'$'}input) {\n ID\n Stav\n CisloDokladu\n }\n}" @generated public class CreateIssuedInvoice( override val variables: CreateIssuedInvoice.Variables, ) : GraphQLClientRequest<CreateIssuedInvoice.Result> { override val query: String = CREATE_ISSUED_INVOICE override val operationName: String = "CreateIssuedInvoice" override fun responseType(): KClass<CreateIssuedInvoice.Result> = CreateIssuedInvoice.Result::class @generated public data class Variables( @get:JsonProperty(value = "input") public val input: IssuedInvoiceInput, ) /** * Dotazy pro zápis, editaci a mazání S5 objektů */ @generated public data class Result( /** * Faktura vydaná (zápis) */ public val CreateIssuedInvoice: IssuedInvoice? = null, ) } ``` Genareted after change: ```kotlin public const val CREATE_ISSUED_INVOICE: String = "mutation CreateIssuedInvoice(${'$'}input: IssuedInvoiceInput!) {\n CreateIssuedInvoice(IssuedInvoice: ${'$'}input) {\n ID\n Stav\n CisloDokladu\n }\n}" @generated public class CreateIssuedInvoice( override val variables: CreateIssuedInvoice.Variables, ) : GraphQLClientRequest<CreateIssuedInvoice.Result> { override val query: String = CREATE_ISSUED_INVOICE override val operationName: String = "CreateIssuedInvoice" override fun responseType(): KClass<CreateIssuedInvoice.Result> = CreateIssuedInvoice.Result::class @generated public data class Variables( @get:JsonProperty(value = "input") public val input: IssuedInvoiceInput, ) /** * Dotazy pro zápis, editaci a mazání S5 objektů */ @generated public data class Result( /** * Faktura vydaná (zápis) */ @get:JsonProperty("CreateIssuedInvoice") public val CreateIssuedInvoice: IssuedInvoice? = null, ) } ``` data class IssuedInvoice **before** change: ```kotlin @generated public data class IssuedInvoice( /** * ID */ @JsonSerialize(converter = UUIDToAnyConverter::class) @JsonDeserialize(converter = AnyToUUIDConverter::class) public val ID: UUID? = null, /** * Stav */ public val Stav: Int? = null, /** * Číslo dokladu */ public val CisloDokladu: String? = null, ) ``` data class IssuedInvoice **after** change: ```kotlin @generated public data class IssuedInvoice( /** * ID */ @JsonSerialize(converter = UUIDToAnyConverter::class) @JsonDeserialize(converter = AnyToUUIDConverter::class) @get:JsonProperty("ID") public val ID: UUID? = null, /** * Stav */ @get:JsonProperty("Stav") public val Stav: Int? = null, /** * Číslo dokladu */ @get:JsonProperty("CisloDokladu") public val CisloDokladu: String? = null, ) ``` ### 🔗 Related Issues https://kotlinlang.slack.com/archives/CQLNT7B29/p1717655752084109
1 parent bce5bc4 commit 60879c5

File tree

85 files changed

+303
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+303
-0
lines changed

plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generatePropertySpecs.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
package com.expediagroup.graphql.plugin.client.generator.types
1818

1919
import com.expediagroup.graphql.plugin.client.generator.GraphQLClientGeneratorContext
20+
import com.expediagroup.graphql.plugin.client.generator.GraphQLSerializer
2021
import com.expediagroup.graphql.plugin.client.generator.ScalarConverterInfo
2122
import com.expediagroup.graphql.plugin.client.generator.exceptions.DeprecatedFieldsSelectedException
2223
import com.expediagroup.graphql.plugin.client.generator.exceptions.InvalidSelectionSetException
2324
import com.expediagroup.graphql.plugin.client.generator.exceptions.MissingArgumentException
25+
import com.fasterxml.jackson.annotation.JsonProperty
2426
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
2527
import com.fasterxml.jackson.databind.annotation.JsonSerialize
2628
import com.squareup.kotlinpoet.AnnotationSpec
@@ -96,6 +98,16 @@ internal fun generatePropertySpecs(
9698
fieldDefinition.description?.content?.let { kdoc ->
9799
propertySpecBuilder.addKdoc("%L", kdoc)
98100
}
101+
if (context.serializer == GraphQLSerializer.JACKSON) {
102+
// always add @get:JsonProperty annotation as a workaround to Jackson limitations
103+
// related to JavaBean naming conventions
104+
propertySpecBuilder.addAnnotation(
105+
AnnotationSpec.builder(JsonProperty::class)
106+
.useSiteTarget(AnnotationSpec.UseSiteTarget.GET)
107+
.addMember("value = \"$fieldName\"")
108+
.build()
109+
)
110+
}
99111
propertySpecBuilder.build()
100112
}
101113

plugins/client/graphql-kotlin-client-generator/src/test/data/generator/alias/AliasQuery.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.expediagroup.graphql.generated
22

33
import com.expediagroup.graphql.client.Generated
44
import com.expediagroup.graphql.client.types.GraphQLClientRequest
5+
import com.fasterxml.jackson.`annotation`.JsonProperty
56
import kotlin.Boolean
67
import kotlin.String
78
import kotlin.reflect.KClass
@@ -22,10 +23,12 @@ public class AliasQuery : GraphQLClientRequest<AliasQuery.Result> {
2223
/**
2324
* Query that accepts some input arguments
2425
*/
26+
@get:JsonProperty(value = "first")
2527
public val first: Boolean,
2628
/**
2729
* Query that accepts some input arguments
2830
*/
31+
@get:JsonProperty(value = "second")
2932
public val second: Boolean,
3033
)
3134
}

plugins/client/graphql-kotlin-client-generator/src/test/data/generator/alias_nested/AliasNestedQuery.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.expediagroup.graphql.client.Generated
44
import com.expediagroup.graphql.client.types.GraphQLClientRequest
55
import com.expediagroup.graphql.generated.aliasnestedquery.ComplexObject
66
import com.expediagroup.graphql.generated.aliasnestedquery.ComplexObject2
7+
import com.fasterxml.jackson.`annotation`.JsonProperty
78
import kotlin.String
89
import kotlin.reflect.KClass
910

@@ -23,10 +24,12 @@ public class AliasNestedQuery : GraphQLClientRequest<AliasNestedQuery.Result> {
2324
/**
2425
* Query returning an object that references another object
2526
*/
27+
@get:JsonProperty(value = "first")
2628
public val first: ComplexObject,
2729
/**
2830
* Query returning an object that references another object
2931
*/
32+
@get:JsonProperty(value = "second")
3033
public val second: ComplexObject2,
3134
)
3235
}

plugins/client/graphql-kotlin-client-generator/src/test/data/generator/alias_nested/aliasnestedquery/ComplexObject.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.expediagroup.graphql.generated.aliasnestedquery
22

33
import com.expediagroup.graphql.client.Generated
4+
import com.fasterxml.jackson.`annotation`.JsonProperty
45
import kotlin.String
56

67
/**
@@ -13,5 +14,6 @@ public data class ComplexObject(
1314
/**
1415
* Some object name
1516
*/
17+
@get:JsonProperty(value = "nameA")
1618
public val nameA: String,
1719
)

plugins/client/graphql-kotlin-client-generator/src/test/data/generator/alias_nested/aliasnestedquery/ComplexObject2.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.expediagroup.graphql.generated.aliasnestedquery
22

33
import com.expediagroup.graphql.client.Generated
4+
import com.fasterxml.jackson.`annotation`.JsonProperty
45
import kotlin.String
56

67
/**
@@ -13,5 +14,6 @@ public data class ComplexObject2(
1314
/**
1415
* Some object name
1516
*/
17+
@get:JsonProperty(value = "nameB")
1618
public val nameB: String,
1719
)

plugins/client/graphql-kotlin-client-generator/src/test/data/generator/documentation/DocumentationQuery.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.expediagroup.graphql.generated
33
import com.expediagroup.graphql.client.Generated
44
import com.expediagroup.graphql.client.types.GraphQLClientRequest
55
import com.expediagroup.graphql.generated.documentationquery.DocObject
6+
import com.fasterxml.jackson.`annotation`.JsonProperty
67
import kotlin.String
78
import kotlin.reflect.KClass
89

@@ -22,6 +23,7 @@ public class DocumentationQuery : GraphQLClientRequest<DocumentationQuery.Result
2223
/**
2324
* Query to test doc strings
2425
*/
26+
@get:JsonProperty(value = "docQuery")
2527
public val docQuery: DocObject,
2628
)
2729
}

plugins/client/graphql-kotlin-client-generator/src/test/data/generator/documentation/documentationquery/DocObject.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.expediagroup.graphql.generated.documentationquery
22

33
import com.expediagroup.graphql.client.Generated
4+
import com.fasterxml.jackson.`annotation`.JsonProperty
45
import kotlin.Int
56

67
/**
@@ -11,5 +12,6 @@ public data class DocObject(
1112
/**
1213
* An id with a comment containing % and $ as well
1314
*/
15+
@get:JsonProperty(value = "id")
1416
public val id: Int,
1517
)

plugins/client/graphql-kotlin-client-generator/src/test/data/generator/include_skip_directives/IncludeSkipDirectivesQuery.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ public class IncludeSkipDirectivesQuery(
3636
/**
3737
* Query that returns enum value
3838
*/
39+
@get:JsonProperty(value = "enumQuery")
3940
public val enumQuery: CustomEnum? = null,
4041
/**
4142
* Query that returns wrapper object with all supported scalar types
4243
*/
44+
@get:JsonProperty(value = "scalarQuery")
4345
public val scalarQuery: ScalarWrapper? = null,
4446
)
4547
}

plugins/client/graphql-kotlin-client-generator/src/test/data/generator/include_skip_directives/includeskipdirectivesquery/ScalarWrapper.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.expediagroup.graphql.generated.includeskipdirectivesquery
22

33
import com.expediagroup.graphql.client.Generated
4+
import com.fasterxml.jackson.`annotation`.JsonProperty
45
import kotlin.Int
56

67
/**
@@ -11,5 +12,6 @@ public data class ScalarWrapper(
1112
/**
1213
* A signed 32-bit nullable integer value
1314
*/
15+
@get:JsonProperty(value = "count")
1416
public val count: Int? = null,
1517
)

plugins/client/graphql-kotlin-client-generator/src/test/data/generator/input_hard_coded/HardCodedInputQuery.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.expediagroup.graphql.generated
22

33
import com.expediagroup.graphql.client.Generated
44
import com.expediagroup.graphql.client.types.GraphQLClientRequest
5+
import com.fasterxml.jackson.`annotation`.JsonProperty
56
import kotlin.Boolean
67
import kotlin.String
78
import kotlin.reflect.KClass
@@ -23,6 +24,7 @@ public class HardCodedInputQuery : GraphQLClientRequest<HardCodedInputQuery.Resu
2324
/**
2425
* Query that accepts some input arguments
2526
*/
27+
@get:JsonProperty(value = "inputObjectQuery")
2628
public val inputObjectQuery: Boolean,
2729
)
2830
}

0 commit comments

Comments
 (0)