Only flat schemas allowed in cache?

Hi, I hope someone kind soul can clearify this for me.

Can the Apollo Client Cache only handle flat schemas?

I´m using Apollo Client 3 for a new app and I’m accessing a schema that has sublevels to make it more structured, here an example where related queries are grouped under nodes and variables.

Query: {
   nodes:NodeQuery{
      allNodes[Node]
      node(id: String):Node
  }
  variables:VariableQuery{
    allVariables[Variable]
    variable(id: String):Variable
  }
}

If I’m querying a list of variables the response will be like:

{
    "data": {
        "variables": {
            "allVariables": [
                {
                    "id": "60b497ad5d584b2c42c18f05",
                    "__typename": "Variable"
                },
                {
                    "id": "60b497ad5d584b2c42c18f06",
                    "__typename": "Variable"
                },
                {
                    "id": "60c9c64a90270df936afbe74",
                    "__typename": "Variable"
                }
            ],
            "__typename": "VariableQuery"
        }
    }
}

And the cache will contain:

ROOT_QUERY {
    __typename:"Query"
    variables: {
        __typename:"VariableQuery"
        allVariables : [ 
            {
                __ref: "Variable:60b497ad5d584b2c42c18f05"
                __ref: "Variable:60b497ad5d584b2c42c18f06"
                __ref: "Variable:60c9c64a90270df936afbe74"
            }
         ] 
    }
}

And the response if I query a variable by its id:

{
    "data": {
        "variables": {
            "variable": {
                "id": "60b497ad5d584b2c42c18f05",
                "name": "Variable name",
                "value": "Variable value",
                "__typename": "Variable"
            },
            "__typename": "VariableQuery"
        }
    }
}

But then the cache will be overwritten from the level of ‘variables’:

ROOT_QUERY {
    __typename:"Query"
    variables: {
        __typename:"VariableQuery"
        variable({"id":"60b497ad5d584b2c42c18f05"}) : {
            __ref: "Variable:60b497ad5d584b2c42c18f05"
        }
        
    }
}

In other words, the variable instanses itself are of course in the cache but the list of variable references are not available anymore in the cache (ROOT_QUERY.variables.allVariables).

This seems logical, but it will totally mess up the application. After clicking around in the application for a while, then one single click will cause like 50 server requests. It’s like the Apollo client has no clue about its data but it tries to revalidate a whole bunch of queries and makes many server requests.

So my questions are:

  1. Can Apollo Client Cache only support flat schemas without nested levels?
  2. Or is there a way to make the cache handle the existing schema, grouped as described, that I’m consuming?
  3. Otherwise, how can all queries be structured? (It seems very limiting to have all queries definied flat direct under the root Query.)

All the best,
Magnus

Hi there! Per default, Apollo’s cache builds its cache keys using an object’s typename and id (or _id) fields. Any objects that do not contain both will not be normalized, which is what is happening to your VariableQuery object. So rather than merging the results of the two variables queries together, the second will replace the first one, since Apollo has no way of knowing they belong together. You can solve this simply by returning an id field for your VariableQuery object.

1 Like

Ah, yes of course, that’s so obvious now. Thank you @mindnektar !