https://github.com/graphql-python/graphene-django/issues/596
I would like to output filters/queries into CACHE (JSON) to improve performance when the client calls a query, what are my best options?
When I want to cache I usually do it from the resolver level
from django.core.cache import cache
class MyType(ObjectType):
display_label = String()
def resolve_display_label(self, info, **args):
cache_key = "some_unique_key_based_on_object"
display_label = cache.get(cache_key)
if display_label is not None:
return display_label
display_label = _do_logic_to_get_display_label_
cache.set(cache_key, display_label , 30) # 30 second timeout
return display_label
I know you didn't ask about django in particular but I'm sure there's alternatives that do the same thing.
This is one option I'm sure other people might have other ways of doing this
I use functools lru cache https://docs.python.org/3/library/functools.html
I've seen use of lru_cache, or use anything from https://cachetools.readthedocs.io/en/stable/ both of which are caching per request-handling-worker you are running.
If you're working in a larger company/have more resources... To share the cache across multiple separate processors/machines in a data center we've used memcache. At this point you're getting into general large scale cache system design though that's not really graphene (or even graphql) specific...
@BossGrand Hey thanks for the answer.
Actually, I was using Django, so your code is super useful and I wanted to take a similar approach.
Following this, I have some more questions and thoughts, would be open to any suggestions:
I am using DjangoFilterConnectionField to resolve queries, as for single items, I use Node.Field(Model)... which does not (as per the document) require a "resolve_xxx" method. Because there is no method, I wonder how to put caching logic here.
Because in my case, the API calls is gonna be quite heavy, I hoped to achieve a kind of greedy type of cache, which does not require traffic to the backend at all. Here are the steps required:
With this way, I guess the most optimistic result will be zero calls to the server and all calls to CDN... Another benefit is that it will help clients worldwide since it is easy to have mirror CDNs than having a multi-zone DB instance / API.
I guess we need to hook on to the query serializer process of Graphene, though I am unfamiliar with the project.
Anyway, (2) is just a future projection, but I would be glad if anyone can just help me with (1) for the moment 馃挴 Haha
As for 1. you can create your own resolve_xxx method that would override the resolver generated by graphene_django. You might lose the free filters provided byDjangoFilterConnectionField, not 100% about this you'll have to check yourself
for 2 you could generate the json and upload it from the resolver, but then if you want to avoid any trafic hitting the server you'll have to do the logic to grab it from your frontend client.
@BossGrand Thanks and will post back here when I figure this out. The first step would be to find out how stock resolver is generated
@gotexis any luck?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Most helpful comment
When I want to cache I usually do it from the resolver level
I know you didn't ask about django in particular but I'm sure there's alternatives that do the same thing.
This is one option I'm sure other people might have other ways of doing this