Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Take default values into account when computing field keys #5384

Merged
merged 4 commits into from
Nov 21, 2023

Conversation

martinbonnin
Copy link
Contributor

@martinbonnin martinbonnin commented Nov 20, 2023

See the tests in CacheArgumentTest. Allows to take defaultValues in cache keys into account for queries like so:

query GetFoo($arg: Int! = 42) {
  foo(arg: $arg)
}

Also take this opportunity to fix GQLIntValue and GQLFLoatValue to make them support arbitrary precision numbers.

While these 2 things are not directly linked, they are related as defaultValues were the only places where we would use the GQLIntValue and GQLFLoatValue values.

Closes #5186

I'm not 100% certain yet about the exhaustivity and correctness of the coercion in different cases (see also graphql/graphql-spec#793) but this should provide a good base to build on.

@martinbonnin martinbonnin requested a review from BoD as a code owner November 20, 2023 16:34
Copy link

netlify bot commented Nov 20, 2023

Deploy Preview for apollo-android-docs canceled.

Name Link
🔨 Latest commit da1b418
🔍 Latest deploy log https://app.netlify.com/sites/apollo-android-docs/deploys/655b91c112f0d10008c10bf0

public final fun getName ()Ljava/lang/String;
public final fun getValue ()Ljava/lang/Object;
public final fun getValue ()Lcom/apollographql/apollo3/api/Optional;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change.

@@ -305,7 +306,7 @@ public final class com/apollographql/apollo3/api/CompiledField : com/apollograph
public final fun getType ()Lcom/apollographql/apollo3/api/CompiledType;
public final fun nameWithArguments (Lcom/apollographql/apollo3/api/Executable$Variables;)Ljava/lang/String;
public final fun newBuilder ()Lcom/apollographql/apollo3/api/CompiledField$Builder;
public final fun resolveArgument (Ljava/lang/String;Lcom/apollographql/apollo3/api/Executable$Variables;)Ljava/lang/Object;
public final fun resolveArgument (Ljava/lang/String;Lcom/apollographql/apollo3/api/Executable$Variables;)Lcom/apollographql/apollo3/api/Optional;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. An argument with a variable value is possibly absent if that variable is absent as well and unless we change the signature, there's no way to account for that. We could go through deprecation cycles but given this is a low level API, I'm hoping this is fine.

@@ -351,7 +352,6 @@ public final class com/apollographql/apollo3/api/CompiledGraphQL {
public static final fun -notNull (Lcom/apollographql/apollo3/api/CompiledType;)Lcom/apollographql/apollo3/api/CompiledNotNullType;
public static final fun isComposite (Lcom/apollographql/apollo3/api/CompiledNamedType;)Z
public static final fun keyFields (Lcom/apollographql/apollo3/api/CompiledNamedType;)Ljava/util/List;
public static final fun resolveVariables (Ljava/lang/Object;Lcom/apollographql/apollo3/api/Executable$Variables;)Ljava/lang/Object;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another breaking change. This one was an accidental public I'd say

*
* Anything else is undefined
*/
typealias ApolloJsonElement = Any?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting that this doesn't show in apiDump. I guess it's source-breaking only.

In all cases, I wish I've done that earlier to be able to point in KDoc to what Any? can contain. Naming is very open to suggestions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ApolloJsonElement sounds good to me 👍. I remember doing a similar thing (typealias JsonMap = Map<String, Any?>) in DeferredJsonMerger which made the code less messy.

KotlinSymbols.BooleanAdapter,
defaultValue.value,
KotlinSymbols.NullableAnyAdapter,
defaultValue.codeBlock(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the most important change. serializeVariables now serializes all the variables if asked to (instead of just the boolean variables before)

Comment on lines +84 to +104
/**
* Pull all arguments from the schema as we need them to compute the cache key
*/
val typeDefinition = schema.typeDefinition(parentType)
val actualArguments = fieldDefinition.arguments.map { schemaArgument ->
val operationArgument = arguments.firstOrNull { it.name == schemaArgument.name }

val keyArgs = typeDefinition.keyArgs(name, schema)
val paginationArgs = typeDefinition.paginationArgs(name, schema)

/**
* When passed explicitly, the argument values are coerced (but not their default value)
*/
val userValue = operationArgument?.value?.coerceInExecutableContextOrThrow(schemaArgument.type, schema)
IrArgument(
name = schemaArgument.name,
value = (userValue ?: schemaArgument.defaultValue)?.toIrValue(),
isKey = keyArgs.contains(schemaArgument.name),
isPagination = paginationArgs.contains(schemaArgument.name)
)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the other important change. The CompiledSelections now contain even more schema information.

Copy link
Contributor

@BoD BoD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏

*
* Anything else is undefined
*/
typealias ApolloJsonElement = Any?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ApolloJsonElement sounds good to me 👍. I remember doing a similar thing (typealias JsonMap = Map<String, Any?>) in DeferredJsonMerger which made the code less messy.

@martinbonnin martinbonnin merged commit 8fec9a5 into main Nov 21, 2023
9 checks passed
@martinbonnin martinbonnin deleted the default-values-in-cache-keys branch November 21, 2023 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cache: Variable defaultValues are not taken into account for cache keys
2 participants