Skip to content

Commit

Permalink
Revert "feat(GraphQLQueryRequest): support alias in projections (#563)…
Browse files Browse the repository at this point in the history
…" (#569)

This reverts commit de93775.
  • Loading branch information
Cole Turner authored Jun 1, 2023
1 parent de93775 commit f8a6778
Show file tree
Hide file tree
Showing 12 changed files with 19 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
val javaType = TypeSpec.classBuilder(clazzName)
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC)
.superclass(ParameterizedTypeName.get(className, ClassName.get(getPackageName(), clazzName), ClassName.get(getPackageName(), parent.name), ClassName.get(getPackageName(), root.name)))
.superclass(ParameterizedTypeName.get(className, ClassName.get(getPackageName(), parent.name), ClassName.get(getPackageName(), root.name)))
.addMethod(
MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,14 @@ class ClientApiGeneratorv2(private val config: CodeGenConfig, private val docume
private fun createRootProjection(type: TypeDefinition<*>, prefix: String): CodeGenResult {
val clazzName = "${prefix}ProjectionRoot"
val className = ClassName.get(BaseSubProjectionNode::class.java)
val parentJavaType = TypeVariableName.get("PARENT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?"), TypeVariableName.get("?")))
val rootJavaType = TypeVariableName.get("ROOT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?"), TypeVariableName.get("?")))
val parentJavaType = TypeVariableName.get("PARENT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?")))
val rootJavaType = TypeVariableName.get("ROOT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?")))
val javaType = TypeSpec.classBuilder(clazzName)
.addOptionalGeneratedAnnotation(config)
.addTypeVariable(parentJavaType)
.addTypeVariable(rootJavaType)
.addModifiers(Modifier.PUBLIC)
.superclass(ParameterizedTypeName.get(className, ClassName.get(getPackageName(), clazzName), TypeVariableName.get("PARENT"), TypeVariableName.get("ROOT")))
.superclass(ParameterizedTypeName.get(className, TypeVariableName.get("PARENT"), TypeVariableName.get("ROOT")))
.addMethod(
MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC)
Expand Down Expand Up @@ -333,14 +333,14 @@ class ClientApiGeneratorv2(private val config: CodeGenConfig, private val docume
private fun createEntitiesRootProjection(federatedTypes: List<ObjectTypeDefinition>): CodeGenResult {
val clazzName = "EntitiesProjectionRoot"
val className = ClassName.get(BaseSubProjectionNode::class.java)
val parentType = TypeVariableName.get("PARENT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?"), TypeVariableName.get("?")))
val rootType = TypeVariableName.get("ROOT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?"), TypeVariableName.get("?")))
val parentType = TypeVariableName.get("PARENT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?")))
val rootType = TypeVariableName.get("ROOT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?")))
val javaType = TypeSpec.classBuilder(clazzName)
.addOptionalGeneratedAnnotation(config)
.addTypeVariable(parentType)
.addTypeVariable(rootType)
.addModifiers(Modifier.PUBLIC)
.superclass(ParameterizedTypeName.get(className, ClassName.get(getPackageName(), clazzName), TypeVariableName.get("PARENT"), TypeVariableName.get("ROOT")))
.superclass(ParameterizedTypeName.get(className, TypeVariableName.get("PARENT"), TypeVariableName.get("ROOT")))
.addMethod(
MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC)
Expand Down Expand Up @@ -480,14 +480,14 @@ class ClientApiGeneratorv2(private val config: CodeGenConfig, private val docume
val clazzName = "${prefix}Projection"
if (generatedClasses.contains(clazzName)) return null else generatedClasses.add(clazzName)

val parentJavaType = TypeVariableName.get("PARENT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?"), TypeVariableName.get("?")))
val rootJavaType = TypeVariableName.get("ROOT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?"), TypeVariableName.get("?")))
val parentJavaType = TypeVariableName.get("PARENT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?")))
val rootJavaType = TypeVariableName.get("ROOT").withBounds(ParameterizedTypeName.get(className, TypeVariableName.get("?"), TypeVariableName.get("?")))
val javaType = TypeSpec.classBuilder(clazzName)
.addOptionalGeneratedAnnotation(config)
.addTypeVariable(parentJavaType)
.addTypeVariable(rootJavaType)
.addModifiers(Modifier.PUBLIC)
.superclass(ParameterizedTypeName.get(className, ClassName.get(getPackageName(), clazzName), TypeVariableName.get("PARENT"), TypeVariableName.get("ROOT")))
.superclass(ParameterizedTypeName.get(className, TypeVariableName.get("PARENT"), TypeVariableName.get("ROOT")))
.addMethod(
MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ class ClientApiGenFragmentTest {
.doesNotContain("duration")

val superclass = codeGenResult.clientProjections[3].typeSpec.superclass as ParameterizedTypeName
assertThat(superclass.typeArguments[1]).extracting("simpleName").isEqualTo("Search_ShowProjection")
assertThat(superclass.typeArguments[2]).extracting("simpleName").isEqualTo("SearchProjectionRoot")
assertThat(superclass.typeArguments[1]).extracting("simpleName").isEqualTo("SearchProjectionRoot")

assertCompilesJava(
codeGenResult.clientProjections + codeGenResult.javaQueryTypes + codeGenResult.javaEnumTypes + codeGenResult.javaDataTypes + codeGenResult.javaInterfaces
Expand Down Expand Up @@ -226,8 +225,7 @@ class ClientApiGenFragmentTest {
assertThat(codeGenResult.clientProjections[3].typeSpec.initializerBlock.isEmpty).isFalse

val superclass = codeGenResult.clientProjections[3].typeSpec.superclass as ParameterizedTypeName
assertThat(superclass.typeArguments[1]).extracting("simpleName").isEqualTo("Search_ResultProjection")
assertThat(superclass.typeArguments[2]).extracting("simpleName").isEqualTo("SearchProjectionRoot")
assertThat(superclass.typeArguments[1]).extracting("simpleName").isEqualTo("SearchProjectionRoot")

val searchResult = codeGenResult.javaInterfaces[0].typeSpec

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ abstract class BaseProjectionNode(
) {

val fields: MutableMap<String, Any?> = LinkedHashMap()
val aliases: MutableMap<String, FieldAlias> = LinkedHashMap()
val fragments: MutableList<BaseProjectionNode> = LinkedList()
val inputArguments: MutableMap<String, List<InputArgument>> = LinkedHashMap()

data class InputArgument(val name: String, val value: Any?)
data class FieldAlias(val fieldName: String, val value: Any?)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,60 +18,19 @@ package com.netflix.graphql.dgs.client.codegen

import java.util.*

abstract class BaseSubProjectionNode<S, T, R>(
abstract class BaseSubProjectionNode<T, R>(
val parent: T,
val root: R,
schemaType: Optional<String> = Optional.empty()
) : BaseProjectionNode(schemaType) {

constructor(parent: T, root: R) : this(parent, root, schemaType = Optional.empty())

fun parent(): T {
return parent
}

fun root(): R {
return root
}

fun alias(alias: String, assigner: (node: S) -> Any): S {
// Avoid alias against existing field name
if (this.javaClass.kotlin.members.any { it.name.equals(alias, ignoreCase = true) }) {
throw AssertionError("Tried to specify alias $alias which already exists as field.")
}

// Stash our current set of fields
val currentFields = fields.toMap()
val currentInputArguments = inputArguments.toMap()
fields.clear()
inputArguments.clear()

// Track the aliased field
@Suppress("UNCHECKED_CAST")
assigner(this as S)

// Constraints on how aliases are assigned
if (fields.isEmpty()) {
throw AssertionError("Tried to initialize alias but did not call any fields.")
}

if (fields.size > 1) {
throw AssertionError("Tried to call multiple fields while initializing alias.")
}

val fieldName = fields.keys.first()
val fieldValue = fields.values.first()
val fieldArguments = mapOf(alias to inputArguments[fieldName]?.let { it }.orEmpty())

// Restore our fields stash
fields.clear()
fields.putAll(currentFields)
inputArguments.clear()
inputArguments.putAll(currentInputArguments)

// Layer in our new state
aliases[alias] = FieldAlias(fieldName = fieldName, value = fieldValue)
inputArguments.putAll(fieldArguments)

return this
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class GraphQLMultiQueryRequest(
}

if (request.projection != null) {
val selectionSet = if (request.projection is BaseSubProjectionNode<*, *, *>) {
val selectionSet = if (request.projection is BaseSubProjectionNode<*, *>) {
request.projectionSerializer.toSelectionSet(request.projection.root() as BaseProjectionNode)
} else {
request.projectionSerializer.toSelectionSet(request.projection)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class GraphQLQueryRequest @JvmOverloads constructor(
}

if (projection != null) {
val selectionSetFromProjection = if (projection is BaseSubProjectionNode<*, *, *> && projection.root() != null) {
val selectionSetFromProjection = if (projection is BaseSubProjectionNode<*, *> && projection.root() != null) {
projectionSerializer.toSelectionSet(projection.root() as BaseProjectionNode)
} else {
projectionSerializer.toSelectionSet(projection)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,30 +51,6 @@ class ProjectionSerializer(private val inputValueSerializer: InputValueSerialize
selectionSet.selection(fieldSelection.build())
}

for ((fieldName, fieldAlias) in projection.aliases) {
val fieldSelection = Field.newField()
.name(fieldAlias.fieldName)
.alias(fieldName)
.arguments(
projection.inputArguments[fieldName].orEmpty().map { (argName, values) ->
Argument(argName, inputValueSerializer.toValue(values))
}
)
if (fieldAlias.value is BaseProjectionNode) {
val fieldSelectionSet = toSelectionSet(fieldAlias.value)
if (fieldSelectionSet.selections.isNotEmpty()) {
fieldSelection.selectionSet(fieldSelectionSet)
}
} else if (fieldAlias.value != null) {
fieldSelection.selectionSet(
SelectionSet.newSelectionSet()
.selection(Field.newField(fieldAlias.value.toString()).build())
.build()
)
}
selectionSet.selection(fieldSelection.build())
}

for (fragment in projection.fragments) {
val typeCondition = fragment.schemaType.map { TypeName(it) }
.orElseGet {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public ShowsProjectionRoot releaseYear() {
return this;
}

public static class Shows_ReviewsProjection extends BaseSubProjectionNode<Shows_ReviewsProjection, ShowsProjectionRoot, ShowsProjectionRoot> {
public static class Shows_ReviewsProjection extends BaseSubProjectionNode<ShowsProjectionRoot, ShowsProjectionRoot> {
public Shows_ReviewsProjection(ShowsProjectionRoot parent, ShowsProjectionRoot root) {
super(parent, root);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,37 +102,4 @@ internal class ProjectionSerializerTest {
""".trimMargin()
)
}

@Test
fun `Projection supports aliases`() {
// given
val root = EntitiesProjectionRoot()
.onMovie(Optional.empty())
.moveId().title().releaseYear()
.alias("colesReviews") { it.reviews("Cole", 10).username().score() }
.reviews(username = "Foo", score = 10).username().score()
.root()
// when
val serialized = ProjectionSerializer(InputValueSerializer()).serialize(root)
// then
assertThat(serialized).isEqualTo(
"""{
| ... on EntitiesMovieKey {
| __typename
| moveId
| title
| releaseYear
| reviews(username: "Foo", score: 10) {
| username
| score
| }
| colesReviews: reviews(username: "Cole", score: 10) {
| username
| score
| }
| }
|}
""".trimMargin()
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class EntitiesMovieKeyProjection(
parent: EntitiesProjectionRoot,
root: EntitiesProjectionRoot,
schemaType: Optional<String>
) : BaseSubProjectionNode<EntitiesMovieKeyProjection, EntitiesProjectionRoot, EntitiesProjectionRoot>(
) : BaseSubProjectionNode<EntitiesProjectionRoot, EntitiesProjectionRoot>(
parent,
root,
schemaType = schemaType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ package com.netflix.graphql.dgs.client.codegen.exampleprojection
import com.netflix.graphql.dgs.client.codegen.BaseSubProjectionNode

class Movies_ReviewsProjection(parent: EntitiesMovieKeyProjection, root: EntitiesProjectionRoot) :
BaseSubProjectionNode<Movies_ReviewsProjection, EntitiesMovieKeyProjection, EntitiesProjectionRoot>(parent, root) {
BaseSubProjectionNode<EntitiesMovieKeyProjection, EntitiesProjectionRoot>(parent, root) {
fun username(): Movies_ReviewsProjection {
fields["username"] = null
return this
Expand Down

0 comments on commit f8a6778

Please sign in to comment.