Apollo-android: [Bug] Incomplete query cache key

Created on 18 Sep 2020  路  6Comments  路  Source: apollographql/apollo-android

Summary
"RESPONSE_FIELDS" in "Content.Data" class of generated GetContentQuery.kt file contains wrong value for "_or" and "_and" expressions.
As a result, queries with different parameters get wrong cache values and overwrite each other

Version
2.3.1

Description
Query request should contain "_and" or "_or" expressions with input parameters in it.

Example query:

query getContent(
  $vendors: [Int!],
  $tags_filter_1: [Int!],
  $tags_filter_2: [Int!]
) {
  content(
    where:{
      state: {_eq: "available"},
      vendor_id: {_in: $vendors},
      _and : [
        { recipe_tags : { tag_id: {_in: $tags_filter_1}}},
        { recipe_tags : { tag_id: {_in: $tags_filter_2}}}
      ]
    }
  ) {id}
}

Generated code:

private val RESPONSE_FIELDS: Array<ResponseField> = arrayOf(
    ResponseField.forList("content", "content", mapOf<String, Any>(
        "where" to mapOf<String, Any>(
            "_and" to
            "[{recipe_tags={tag_id={_in={kind=Variable, variableName=tags_filter_1}}}}, {recipe_tags={tag_id={_in={kind=Variable, variableName=tags_filter_2}}}}]",            
            "vendor_id" to mapOf<String, Any>(
                "_in" to mapOf<String, Any>(
                    "kind" to "Variable",
                    "variableName" to "vendors"))
        )
    )))

The content of "_and" tag is not parsed.

This data is used by RealCacheKeyBuilder.kt
for generating unique query key to get valid data from cache.

In current case, cache key generator skip variables in "_and" block, and queries with different params (tags_filter_1, tags_filter_2) generate the same cache key.

Solution
Code generator should expand "_and" field value.
Temporary solution is to edit generated code in project this way:

"_and" to mapOf<String, Any>(
    "content_tags1" to mapOf<String, Any>(
        "_in" to mapOf<String, Any>(
        "kind" to "Variable",
        "variableName" to "tags_filter_1")),
    "content_tags2" to mapOf<String, Any>(
        "_in" to mapOf<String, Any>(
        "kind" to "Variable",
        "variableName" to "tags_filter_2"))
)

In future versions, should be added possibility to use List>
Plugin should generate code like this:

"_and" to listOf<Pair<String, Any>>(
    "content_tags" to mapOf<String, Any>(
        "_in" to mapOf<String, Any>(
        "kind" to "Variable",
        "variableName" to "tags_filter_1")),
    "content_tags" to mapOf<String, Any>(
        "_in" to mapOf<String, Any>(
        "kind" to "Variable",
        "variableName" to "tags_filter_2"))
)
Bug

All 6 comments

Vote for fix!

+1
This fix is highly demanded for our project.

Thanks for the bug report! Tentative fix there: https://github.com/apollographql/apollo-android/pull/2592

@Rangot @moshkit @alexandrim0 The fix is now merged. Any chance you can confirm it works for you with version 2.4.1-SNAPSHOT ? (See https://github.com/apollographql/apollo-android#snapshots for how to include snapshots repositories)

Edit: Ooops, looks like I spoke too fast, pushing the SNAPSHOT failed in latest CI build, I just relaunched the build, it should be there in a few...

Edit2: All good, we have updated SNAPSHOTs in OSS 馃憤 , let me know how that goes: https://oss.sonatype.org/content/repositories/snapshots/com/apollographql/apollo/apollo-api/2.4.1-SNAPSHOT/

Need some time for checking.
Thank you!

@martinbonnin

2610

  • Code generation is ok
  • Bug with overriding cache keys: fixed!

Thank you a lot!

Was this page helpful?
0 / 5 - 0 ratings