Skip to content

Commit

Permalink
Add a __typename method on projections for selection. (#685)
Browse files Browse the repository at this point in the history
* Use concrete types for JsonSubType annotations on interfaces if available.

* Add a __typename() method to select on projections.
  • Loading branch information
srinivasankavitha authored Apr 24, 2024
1 parent d7646cd commit 30ac67d
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,20 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
.build()
)

val typeVariable = TypeVariableName.get("$clazzName<PARENT, ROOT>")
javaType.addMethod(
MethodSpec.methodBuilder(TypeNameMetaFieldDef.name)
.returns(typeVariable)
.addCode(
"""
|getFields().put("${TypeNameMetaFieldDef.name}", null);
|return this;
""".trimMargin()
)
.addModifiers(Modifier.PUBLIC)
.build()
)

if (generatedClasses.contains(clazzName)) return CodeGenResult() else generatedClasses.add(clazzName)

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

// add a method for setting the __typename
val typeVariable = TypeVariableName.get("$clazzName<PARENT, ROOT>")
javaType.addMethod(
MethodSpec.methodBuilder(TypeNameMetaFieldDef.name)
.returns(typeVariable)
.addCode(
"""
|getFields().put("${TypeNameMetaFieldDef.name}", null);
|return this;
""".trimMargin()
)
.addModifiers(Modifier.PUBLIC)
.build()
)

val fieldDefinitions = type.fieldDefinitions() +
document.definitions
.filterIsInstance<ObjectTypeExtensionDefinition>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class ClientApiGenFragmentTest {
assertThat(codeGenResult.clientProjections.size).isEqualTo(3)
assertThat(codeGenResult.clientProjections[0].typeSpec.name).isEqualTo("SearchProjectionRoot")
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("title")
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("__typename")
assertThat(codeGenResult.clientProjections[1].typeSpec.name).isEqualTo("MovieFragmentProjection")
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs).extracting("name").contains("duration")
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs).extracting("name").contains("title")
Expand Down Expand Up @@ -114,8 +115,10 @@ class ClientApiGenFragmentTest {

assertThat(codeGenResult.clientProjections.size).isEqualTo(4)
assertThat(codeGenResult.clientProjections[0].typeSpec.name).isEqualTo("SearchProjectionRoot")
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("__typename")
assertThat(codeGenResult.clientProjections[1].typeSpec.name).isEqualTo("ShowProjection")
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs).extracting("name").contains("title")
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs).extracting("name").contains("__typename")
assertThat(codeGenResult.clientProjections[2].typeSpec.name).isEqualTo("MovieFragmentProjection")
assertThat(codeGenResult.clientProjections[2].typeSpec.methodSpecs).extracting("name").contains("duration")
assertThat(codeGenResult.clientProjections[2].typeSpec.methodSpecs).extracting("name").contains("title")
Expand Down Expand Up @@ -160,6 +163,7 @@ class ClientApiGenFragmentTest {

assertThat(codeGenResult.clientProjections.size).isEqualTo(3)
assertThat(codeGenResult.clientProjections[0].typeSpec.name).isEqualTo("SearchProjectionRoot")
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("__typename")
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("onMovie")
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs).extracting("name").contains("onActor")
assertThat(codeGenResult.clientProjections[1].typeSpec.name).isEqualTo("MovieFragmentProjection")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ class ClientApiGenProjectionTest {
val projections = codeGenResult.clientProjections
assertThat(projections.size).isEqualTo(1)
assertThat(projections[0].typeSpec.name).isEqualTo("PeopleProjectionRoot")
assertThat(projections[0].typeSpec.methodSpecs.size).isEqualTo(3)
assertThat(projections[0].typeSpec.methodSpecs).extracting("name").contains("name", "email")
assertThat(projections[0].typeSpec.methodSpecs.size).isEqualTo(4)
assertThat(projections[0].typeSpec.methodSpecs).extracting("name").contains("name", "email", "__typename")

assertCompilesJava(codeGenResult)
}
Expand Down Expand Up @@ -404,8 +404,8 @@ class ClientApiGenProjectionTest {
val projections = codeGenResult.clientProjections
assertThat(projections.size).isEqualTo(2)
assertThat(projections[1].typeSpec.name).isEqualTo("MovieProjection")
assertThat(projections[1].typeSpec.methodSpecs.size).isEqualTo(3)
assertThat(projections[1].typeSpec.methodSpecs).extracting("name").contains("title", "director", "<init>")
assertThat(projections[1].typeSpec.methodSpecs.size).isEqualTo(4)
assertThat(projections[1].typeSpec.methodSpecs).extracting("name").contains("title", "director", "<init>", "__typename")

assertCompilesJava(codeGenResult)
}
Expand Down Expand Up @@ -441,7 +441,7 @@ class ClientApiGenProjectionTest {
val projections = codeGenResult.clientProjections
assertThat(projections.size).isEqualTo(2)
assertThat(projections[1].typeSpec.name).isEqualTo("MovieProjection")
assertThat(projections[1].typeSpec.methodSpecs.size).isEqualTo(3)
assertThat(projections[1].typeSpec.methodSpecs.size).isEqualTo(4)
assertThat(projections[1].typeSpec.methodSpecs).extracting("name").contains("title", "director", "<init>")

assertCompilesJava(codeGenResult)
Expand Down Expand Up @@ -716,7 +716,7 @@ class ClientApiGenProjectionTest {
).generate()

val methodSpecs = codeGenResult.clientProjections[0].typeSpec.methodSpecs
assertThat(methodSpecs.size).isEqualTo(3)
assertThat(methodSpecs.size).isEqualTo(4)
val methodWithArgs = methodSpecs.find { it.parameters.size > 0 && it.name == "actors" }
?: fail("Expected method not found")
assertThat(methodWithArgs.parameters[0].name).isEqualTo("leadCharactersOnly")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -441,11 +441,11 @@ class ClientApiGenQueryTest {
assertThat(codeGenResult.javaQueryTypes[0].typeSpec.name).isEqualTo("SearchGraphQLQuery")
assertThat(codeGenResult.clientProjections.size).isEqualTo(3)
assertThat(codeGenResult.clientProjections[0].typeSpec.name).isEqualTo("SearchProjectionRoot")
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs[1].name).isEqualTo("title")
assertThat(codeGenResult.clientProjections[0].typeSpec.methodSpecs[2].name).isEqualTo("title")
assertThat(codeGenResult.clientProjections[1].typeSpec.name).isEqualTo("MovieFragmentProjection")
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs[2].name).isEqualTo("duration")
assertThat(codeGenResult.clientProjections[1].typeSpec.methodSpecs[3].name).isEqualTo("duration")
assertThat(codeGenResult.clientProjections[2].typeSpec.name).isEqualTo("SeriesFragmentProjection")
assertThat(codeGenResult.clientProjections[2].typeSpec.methodSpecs[2].name).isEqualTo("episodes")
assertThat(codeGenResult.clientProjections[2].typeSpec.methodSpecs[3].name).isEqualTo("episodes")

assertCompilesJava(
codeGenResult.clientProjections + codeGenResult.javaQueryTypes + codeGenResult.javaEnumTypes + codeGenResult.javaDataTypes + codeGenResult.javaInterfaces
Expand Down

0 comments on commit 30ac67d

Please sign in to comment.