amplify-category-api
amplify-category-api copied to clipboard
How to cache the query response?
Amplify CLI Version
12.10.0
Question
I have a mode like this below
type Integration @model @searchable @auth(rules: [{allow: public}, {allow: custom}]) {
enterpriseId: ID!
@primaryKey(sortKeyFields: ["mode", "integrationId"])
mode: MODE!
integrationId: ID!
config: AWSJSON
}
I have enabled caching in appsync, with TTL of 3600s with Full Resolver caching
I did do a getIntegration by passing enterpriseId, mode, integrationId
However for the second time, i still see the response time being same and cache miss, there are no cache hits
I did check the VTL context , but couldn't understand much Below is how the request VTL looks like
## [Start] Get Request template. **
#set( $GetRequest = {
"version": "2018-05-29",
"operation": "Query"
} )
#if( $ctx.stash.metadata.modelObjectKey )
#set( $expression = "" )
#set( $expressionNames = {} )
#set( $expressionValues = {} )
#foreach( $item in $ctx.stash.metadata.modelObjectKey.entrySet() )
#set( $expression = "$expression#keyCount$velocityCount = :valueCount$velocityCount AND " )
$util.qr($expressionNames.put("#keyCount$velocityCount", $item.key))
$util.qr($expressionValues.put(":valueCount$velocityCount", $item.value))
#end
#set( $expression = $expression.replaceAll("AND $", "") )
#set( $query = {
"expression": $expression,
"expressionNames": $expressionNames,
"expressionValues": $expressionValues
} )
#else
#set( $query = {
"expression": "id = :id",
"expressionValues": {
":id": $util.parseJson($util.dynamodb.toDynamoDBJson($ctx.args.id))
}
} )
#end
$util.qr($GetRequest.put("query", $query))
#if( !$util.isNullOrEmpty($ctx.stash.authFilter) )
$util.qr($GetRequest.put("filter", $util.parseJson($util.transform.toDynamoDBFilterExpression($ctx.stash.authFilter))))
#end
$util.toJson($GetRequest)
## [End] Get Request template. **
How to make caching work with amplify? for the above scenario?
I enabled Per-resolver caching by following this https://aws.amazon.com/blogs/mobile/appsync-pipeline-caching/ I was able to see the cache hits in the logs as well
However, how do i evict the cache now?
I can think of these approaches, please suggest if there is a better one, or which one is better?
- Per resolver, need to modify the VTL in response to evict based on the cache keys? This looks like a tedious job?
- Is there a custom directive, which can handle this? if we can pass the cache key? for mutations, evict can happen?
After looking at the available options, i think PER_RESOLVER caching with @cache directive is the best approach to go forward
I will give it a try to create a custom cache directive, which can take ttl and cache keys - which can be set on a @model
or is there a way to extend the @model transformer itself?
As you have discovered there is no native support for caching in the Amplify GraphQL API. Either of the two options you outlined would be a good option. There is no way to modify the @model transformer outside of creating a fork of the project. I think creating a custom transformer with the @cache directive is your best option.
@dpilch Thanks
However i realised without the cache eviction flexible (support to evict based on regex) (i do understand why it cant be flexible - as it hampers the performance)
and also dynamoDB being the database, does it really make sense to have cache?
We might be saving few bugs with the read queries, apart from this, i don't see any advantage
What are your thoughts on this?
I agree it might not be worth the effort. Have you considered a client side cache?
Thanks for sharing you view
It's an event driven architecture, most of the calls are from lambda, I feel it's better to relook business logic and access patterns
Also I see, AppSync take sometime to execute queries. Is it because of the cold starts? I understand it's out of context, but I couldn't find related info (may be because I am wrong) - in X-ray even though I see dynamodb calls take 30ms, the overall app sync request take 300ms (or is it because of network latency?)
How to reduce the latency in this case? I dont see a provisioned capacity for appsync like how we have for lambda
It's hard to pinpoint the source of the latency. Are you still experiencing higher than desired latency?
Hey 👋 , This issue is being closed due to inactivity. If you are still experiencing the same problem and need further assistance, please feel free to leave a comment. This will enable us to reopen the issue and provide you with the necessary support.
This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.