wp-graphql / wp-graphql-smart-cache

Smart Caching & Cache Invalidation for WPGraphQL

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can we exclude specific queries from being cached?

alexkey89 opened this issue · comments

e.g When I activated smart cache, customer query was getting cached. I want to be able to exclude specific queries so that they are never cached simply by sending a variable in the request or having the specified queries in settings page. i created this snippet as a hack. If a more advanced php person can solve this in better way with new release, that would be great.

So every time I request it will toggle the cache. However this isn't ideal.

add_action( 'init', function() {
    if (
        $_SERVER['REQUEST_METHOD'] === 'POST' &&
        isset( $_REQUEST['disable_cache'] )
    ) {
        if ( is_plugin_active( 'wp-graphql-smart-cache/wp-graphql-smart-cache.php' ) ) {
            add_filter( 'graphql_get_setting_section_field_value', function( $value, $default, $option_name, $section_fields, $section_name ) {
                if ( $option_name === 'cache_toggle' ) {
                    return false;
                }
                return $value;
            }, 10, 5 );
        }
    }
} );

@alexkey89 I'd like to hear more about the use cases for when you want the client to bypass the cache. Ideally, if things are working as expected, you should get faster responses from the cache, and updated data when things change. It should be a good balance of faster responses and accurate data.

I'd love to learn more about your use cases and how we can support them.

@jasonbahl I don't want for example the customer order query to be cached. Otherwise it will cache data that are not supposed to be cached. like sensitive data. e.g i don't want this query to be cached:

query GET_CUSTOMER_ORDERS($id: Int, $first: Int, $after: String) {
  customer(customerId: $id) {
    firstName
    lastName
    email
    orders(first:$first, after:$after){
      pageInfo{
        endCursor
        startCursor
        hasNextPage
        hasPreviousPage
        total
      }
      edges{
        node{
          orderNumber
          databaseId
          date
          status
          lineItems {
            edges {
              node {
                databaseId
                orderId
                productId
                product{
                  node{
                    image{
                      sourceUrl
                    }
                  }
                }
                quantity
                subtotal
                subtotalTax
                taxClass
                taxStatus
                total
                totalTax
                variationId
              }
            }
          }
          currency
          refunds {
            edges {
              node {
                id
              }
            }
          }
          total
        }
      }
    }
  }
}

As I explained, I want to exclude specific queries from cache, that's why I created the php snippet above.

@alexkey89 thanks for the info. Is the customer data publicly queryable currently? Or do you need to be authenticated to query it? Right now we don't cache if the request is authenticated, and it seems like customer data would probably be restricted to authenticated users?

That said, I have a good idea for making this easier. I'll work on a PR that introduces a new filter to make it easier to conditionally enable/disable the cache mechanisms per-query (or other condition)

@alexkey89 I've opened a PR introducing a new filter that I believe will make your situation a bit easier: #178

@jasonbahl Thanks for the filter! I'll give it a go when ready. As for the customer data, I'm doing the query after user is authenticated yes but when I enabled smart cache, I noticed a lot of inconsistencies on that. Maybe with switching off cache on that query it will solve it.

@alexkey89 I'd love to learn more about the inconstancies you're seeing. There might be a bug we need to fix.

At the moment we shouldn't be caching authenticated queries or returning cached responses from authenticated queries.

Are you doing these queries over GET or POST requests?

Do you have steps I could follow to reproduce the same behavior you were seeing?

Hi @jasonbahl I didn't have time to test it so I used fastly CDN edge caching for the headless woocommerce site was doing. it's now fully released. There, I could select specific queries to get cached or not. Stellate didn't have great flexibility or support. Fastly however is really expensive. Smart cache seems the way to go but... when I tested last time, it was interfering with the loginWithCookies mutation(wasn't working). If you want me to I can start a sample site and test it again.