Graphene: CACHE queries (Django first) (Node.Field / Generate Json file?)

Created on 16 Mar 2019  路  8Comments  路  Source: graphql-python/graphene

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?

question wontfix

Most helpful comment

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

All 8 comments

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'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:

  1. 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.

  2. 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:

    • query once, and serialize the output into JSON file (may even be done periodically through Celery)
    • save the JSON into S3 storage, automatically uploaded to CDN
    • frontend (Vue) fetch that JSON before attempting to query the server. If the cache is too old or not present, can query the server.

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.

Was this page helpful?
0 / 5 - 0 ratings