Skip to content

Commit 30ac67d

Browse files
Add a __typename method on projections for selection. (#685)
* Use concrete types for JsonSubType annotations on interfaces if available. * Add a __typename() method to select on projections.
1 parent d7646cd commit 30ac67d

File tree

4 files changed

+42
-9
lines changed

4 files changed

+42
-9
lines changed

graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/ClientApiGenerator.kt

+29
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,20 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
256256
.build()
257257
)
258258

259+
val typeVariable = TypeVariableName.get("$clazzName<PARENT, ROOT>")
260+
javaType.addMethod(
261+
MethodSpec.methodBuilder(TypeNameMetaFieldDef.name)
262+
.returns(typeVariable)
263+
.addCode(
264+
"""
265+
|getFields().put("${TypeNameMetaFieldDef.name}", null);
266+
|return this;
267+
""".trimMargin()
268+
)
269+
.addModifiers(Modifier.PUBLIC)
270+
.build()
271+
)
272+
259273
if (generatedClasses.contains(clazzName)) return CodeGenResult() else generatedClasses.add(clazzName)
260274

261275
val fieldDefinitions = type.fieldDefinitions() + document.definitions.filterIsInstance<ObjectTypeExtensionDefinition>().filter { it.name == type.name }.flatMap { it.fieldDefinitions }
@@ -534,6 +548,21 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
534548
.build()
535549
)
536550

551+
// add a method for setting the __typename
552+
val typeVariable = TypeVariableName.get("$clazzName<PARENT, ROOT>")
553+
javaType.addMethod(
554+
MethodSpec.methodBuilder(TypeNameMetaFieldDef.name)
555+
.returns(typeVariable)
556+
.addCode(
557+
"""
558+
|getFields().put("${TypeNameMetaFieldDef.name}", null);
559+
|return this;
560+
""".trimMargin()
561+
)
562+
.addModifiers(Modifier.PUBLIC)
563+
.build()
564+
)
565+
537566
val fieldDefinitions = type.fieldDefinitions() +
538567
document.definitions
539568
.filterIsInstance<ObjectTypeExtensionDefinition>()

graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenFragmentTest.kt

+4
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class ClientApiGenFragmentTest {
6161
assertThat(codeGenResult.clientProjections.size).isEqualTo(3)
6262
assertThat(codeGenResult.clientProjections[0].typeSpec.name).isEqualTo("SearchProjectionRoot")
6363
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("title")
64+
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("__typename")
6465
assertThat(codeGenResult.clientProjections[1].typeSpec.name).isEqualTo("MovieFragmentProjection")
6566
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs).extracting("name").contains("duration")
6667
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs).extracting("name").contains("title")
@@ -114,8 +115,10 @@ class ClientApiGenFragmentTest {
114115

115116
assertThat(codeGenResult.clientProjections.size).isEqualTo(4)
116117
assertThat(codeGenResult.clientProjections[0].typeSpec.name).isEqualTo("SearchProjectionRoot")
118+
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("__typename")
117119
assertThat(codeGenResult.clientProjections[1].typeSpec.name).isEqualTo("ShowProjection")
118120
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs).extracting("name").contains("title")
121+
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs).extracting("name").contains("__typename")
119122
assertThat(codeGenResult.clientProjections[2].typeSpec.name).isEqualTo("MovieFragmentProjection")
120123
assertThat(codeGenResult.clientProjections[2].typeSpec.methodSpecs).extracting("name").contains("duration")
121124
assertThat(codeGenResult.clientProjections[2].typeSpec.methodSpecs).extracting("name").contains("title")
@@ -160,6 +163,7 @@ class ClientApiGenFragmentTest {
160163

161164
assertThat(codeGenResult.clientProjections.size).isEqualTo(3)
162165
assertThat(codeGenResult.clientProjections[0].typeSpec.name).isEqualTo("SearchProjectionRoot")
166+
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("__typename")
163167
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("onMovie")
164168
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("onActor")
165169
assertThat(codeGenResult.clientProjections[1].typeSpec.name).isEqualTo("MovieFragmentProjection")

graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenProjectionTest.kt

+6-6
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,8 @@ class ClientApiGenProjectionTest {
367367
val projections = codeGenResult.clientProjections
368368
assertThat(projections.size).isEqualTo(1)
369369
assertThat(projections[0].typeSpec.name).isEqualTo("PeopleProjectionRoot")
370-
assertThat(projections[0].typeSpec.methodSpecs.size).isEqualTo(3)
371-
assertThat(projections[0].typeSpec.methodSpecs).extracting("name").contains("name", "email")
370+
assertThat(projections[0].typeSpec.methodSpecs.size).isEqualTo(4)
371+
assertThat(projections[0].typeSpec.methodSpecs).extracting("name").contains("name", "email", "__typename")
372372

373373
assertCompilesJava(codeGenResult)
374374
}
@@ -404,8 +404,8 @@ class ClientApiGenProjectionTest {
404404
val projections = codeGenResult.clientProjections
405405
assertThat(projections.size).isEqualTo(2)
406406
assertThat(projections[1].typeSpec.name).isEqualTo("MovieProjection")
407-
assertThat(projections[1].typeSpec.methodSpecs.size).isEqualTo(3)
408-
assertThat(projections[1].typeSpec.methodSpecs).extracting("name").contains("title", "director", "<init>")
407+
assertThat(projections[1].typeSpec.methodSpecs.size).isEqualTo(4)
408+
assertThat(projections[1].typeSpec.methodSpecs).extracting("name").contains("title", "director", "<init>", "__typename")
409409

410410
assertCompilesJava(codeGenResult)
411411
}
@@ -441,7 +441,7 @@ class ClientApiGenProjectionTest {
441441
val projections = codeGenResult.clientProjections
442442
assertThat(projections.size).isEqualTo(2)
443443
assertThat(projections[1].typeSpec.name).isEqualTo("MovieProjection")
444-
assertThat(projections[1].typeSpec.methodSpecs.size).isEqualTo(3)
444+
assertThat(projections[1].typeSpec.methodSpecs.size).isEqualTo(4)
445445
assertThat(projections[1].typeSpec.methodSpecs).extracting("name").contains("title", "director", "<init>")
446446

447447
assertCompilesJava(codeGenResult)
@@ -716,7 +716,7 @@ class ClientApiGenProjectionTest {
716716
).generate()
717717

718718
val methodSpecs = codeGenResult.clientProjections[0].typeSpec.methodSpecs
719-
assertThat(methodSpecs.size).isEqualTo(3)
719+
assertThat(methodSpecs.size).isEqualTo(4)
720720
val methodWithArgs = methodSpecs.find { it.parameters.size > 0 && it.name == "actors" }
721721
?: fail("Expected method not found")
722722
assertThat(methodWithArgs.parameters[0].name).isEqualTo("leadCharactersOnly")

graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenQueryTest.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -441,11 +441,11 @@ class ClientApiGenQueryTest {
441441
assertThat(codeGenResult.javaQueryTypes[0].typeSpec.name).isEqualTo("SearchGraphQLQuery")
442442
assertThat(codeGenResult.clientProjections.size).isEqualTo(3)
443443
assertThat(codeGenResult.clientProjections[0].typeSpec.name).isEqualTo("SearchProjectionRoot")
444-
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs[1].name).isEqualTo("title")
444+
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs[2].name).isEqualTo("title")
445445
assertThat(codeGenResult.clientProjections[1].typeSpec.name).isEqualTo("MovieFragmentProjection")
446-
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs[2].name).isEqualTo("duration")
446+
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs[3].name).isEqualTo("duration")
447447
assertThat(codeGenResult.clientProjections[2].typeSpec.name).isEqualTo("SeriesFragmentProjection")
448-
assertThat(codeGenResult.clientProjections[2].typeSpec.methodSpecs[2].name).isEqualTo("episodes")
448+
assertThat(codeGenResult.clientProjections[2].typeSpec.methodSpecs[3].name).isEqualTo("episodes")
449449

450450
assertCompilesJava(
451451
codeGenResult.clientProjections + codeGenResult.javaQueryTypes + codeGenResult.javaEnumTypes + codeGenResult.javaDataTypes + codeGenResult.javaInterfaces

0 commit comments

Comments
 (0)