Cache isn't evicted if $extensions.evictFromApiCache is invoked in nested mutation

0

Hi, title says it all, recently we've made few changes to the mutations and how they are queried, from now on all mutations can nested inside one "main" mutation which made cache eviction impossible for them.

Mutations that aren't invoked by nesting are evicting the cache just fine, but the nested ones does not, despite having the same eviction configuration and working on the same keys, the single difference being the nesting of the mutations.

Since eviction is tied to root mutation response mapping there seems to be no way of working around it. Is it expected behavior? if so, is it described somewhere?

Any support or ideas will be greatly appreciated, thank you :)

There are some details:

Schema:

type Item @aws_iam @aws_api_key @aws_cognito_user_pools {
    id: ID!
    name: String!
}

type Query @aws_iam @aws_api_key @aws_cognito_user_pools {
    fetchItem(id: ID!): Item!
    nested: QueryNested!
}

type QueryNested @aws_iam @aws_api_key @aws_cognito_user_pools {
    fetchItem(id: ID!): Item!
}

type Mutation @aws_iam @aws_api_key @aws_cognito_user_pools {
   changeItemName(id: ID!, name: String): Item!
    nested: MutationNested!
}

type MutationNested @aws_iam @aws_api_key @aws_cognito_user_pools {
    changeItemName(id: ID!, name: String!): Item!
}

Caching keys: $context.arguments.id on Query.fetchItem and QueryNested.fetchItem

Evictions in response mappings (VTL):

Mutation.changeItemName:

$extensions.evictFromApiCache("Query", "fetchItem", {
      "context.arguments.id": $context.arguments.id
    })

MutationNested.changeItemName:

$extensions.evictFromApiCache("QueryNested", "fetchItem", {
      "context.arguments.id": $context.arguments.id
    })

Given Item:

{id: 1, name: "test}

We invoke not nested GQL with below requests and responses, all of them are fine:

  1. Not cached item: Req:
mutation Mutation {
         changeItemName(id:1, name: "not-nested-1") {
             id
             name
             }
}

Res:

{
    "data": {
        "changeItemName": {
            "id": 1,
            "name": "not-nested-1"
        }
    }
}

Req:

mutation Query {
         fetchItem(id:1) {
             id
             name
             }
}

Res:

{
    "data": {
        "fetchItem": {
            "id": 1,
            "name": "not-nested-1"
        }
    }
}

  1. Cached item: Req:
mutation Mutation {
         changeItemName(id:1, name: "not-nested-2") {
             id
             name
             }
}

Res:

{
    "extensions": {
      "apiCacheEntriesDeleted": 1
    },
    "data": {
        "changeItemName": {
            "id": 1,
            "name": "not-nested-2"
        }
    }
}

Req:

mutation Query {
         fetchItem(id:1) {
             id
             name
             }
}

Res:

{
    "data": {
        "fetchItem": {
            "id": 1,
            "name": "not-nested-2"
        }
    }
}

Then we invoke nested GQL with below requests and responses, second mutation does not evict the cache:

  1. Not cached item:

Req:

mutation MutationNested {
         changeItemName(id:1, name: "nested-1") {
             id
             name
             }
}

Res:

{
    "data": {
        "nested":{
            "changeItemName": {
                "id": 1,
                "name": "nested-1"
            }
        }
    }
}

Req:

mutation QueryNested {
         fetchItem(id:1) {
             id
             name
             }
}

Res:

{
    "data": {
        "nested":{
            "fetchItem": {
                "id": 1,
                "name": "nested-1" // OK: Didn't cached "not-nested-2" since its different typeName Query <> QueryNested, caching this response
            }
        }
    }
}
  1. Cached item: Req:
mutation MutationNested {
         changeItemName(id:1, name: "nested-2") {
             id
             name
             }
}

Res:

{
    // Notice lack of the "extension" key
    "data": {
        "nested":{
            "changeItemName": {
                "id": 1,
                "name": "nested-2"
            }
        }
    }
}

Req:

mutation QueryNested {
         fetchItem(id:1) {
             id
             name
             }
}

Res:

{
    "data": {
        "nested":{
            "fetchItem": {
                "id": 1,
                "name": "nested-1"  //NOK should return "nested-2", but instead hit the cache that should be evicted by previous MutationNested.changeItemName invocation.
            }
        }
    }
}

Resources:

  1. extensions doc
  2. article
asked 8 months ago254 views
1 Answer
0

For future explorers: It's still unknown to me why such evict doesn't work in nested mutations but I've managed to find a workaround by changing nested mutations from unit to pipeline type and moving data source along with mappings to separate function and then calling just that one function from the resolver. It's basically wrapping a function with pass-trough resolver.

In that way when evict is invoked in the context of a function (instead of the resolver) even when called from nested resolver then it just works ;)

answered 8 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions