Skip to content

Commit

Permalink
- update license in composer.json
Browse files Browse the repository at this point in the history
- update main README.md
- add individual docs for Cache Invalidation, Extensiond, FAQ, etc
  • Loading branch information
jasonbahl committed Nov 9, 2022
1 parent f9543bb commit 48b5654
Show file tree
Hide file tree
Showing 13 changed files with 666 additions and 313 deletions.
441 changes: 128 additions & 313 deletions README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "wp-graphql/wp-graphql-smart-cache",
"description": "Smart Caching and Cache Invalidation for WPGraphQL",
"type": "wordpress-plugin",
"license": "GPL-3.0-or-later",
"autoload": {
"psr-4": {
"WPGraphQL\\PersistedQueries\\": "src/",
Expand Down
66 changes: 66 additions & 0 deletions docs/cache-invalidation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Cache Invalidation


## GraphQL Cache Invalidation

One of the primary features of the WPGraphQL Smart Cache plugin is the cache invalidation.

Unlike RESTful APIs which are 1 enpdoint per resource type, GraphQL Queries can be constructed in nearly infinite ways, and can contain resources of many types.

Thus, caching and invalidating caches can be tricky.

This is where WPGraphQL Smart Cache really shines.

WPGraphQL Smart Cache listens for events in WordPress, and purges caches for relevant queries in response to said events.

### Invalidation Strategy

When a GraphQL request is executed against the WPGraphQL endpoint, the query is analyzed to determine:

- The operation name of the query
- The ID of the query (a hash of the query document string)
- What types of nodes were asked for as a list
- The individual nodes resolved by the query

The results of this query analysis are returned in the `X-GraphQL-Keys` header.


## Invalidation Strategy

- **Publish Events:** when something is made publicly visible we call purge( `list:$types` )
- **Update Events:** when something public is updated, we call `purge( $node_id )`
- **Delete Events:** when something public is made not-public, we call `purge( $node_id )`

## Tracked Events

### Posts, Pages, Custom Post Types

- published
- updated
- deleted
- meta changes

### Categories, Tags, Custom Taxonomies

- created
- assigned to post
- unassigned to post
- deleted
- meta changes

### Users

- created
- assigned as author of a post
- deleted
- author re-assigned

### Media

- uploaded
- updated
- deleted

### Comments

### Settings / Options
15 changes: 15 additions & 0 deletions docs/extending.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Extending / Customizing WPGraphQL Smart Cache

In this document you will find information related to extending and custimizing the default behaviors of the WPGraphQL Smart Cache plugin.

- [Customizing the X-GraphQL-Keys Header](#customizing-the-x-graphql-keys-header)
- [Purging in response to a custom event](#purging-in-response-to-a-custom-event)

## Customizing the X-GraphQL-Keys Header

@todo


## Purging in response to a custom event

@todo
19 changes: 19 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Frequently Asked Questions

## What's the price of this plugin?

This plugin is free!

## Is the plugin on Composer or the WordPress.org repo?

We plan to put the plugin on Composer and WordPress.org at some point, but currently it's only available on [Github](https://github.com/wp-graphql/wp-graphql-smart-cache/releases/latest).

## Does this plugin only work on WP Engine?

This plugin was built to work in WordPress with as many WordPress hosts.

The [Network Cache](./network-cache.md) functionality does require some work from the host to support.

We've partnered with WP Engine to get this functionality working for WP Engine customers, but we hope to see more hosts support GraphQL caching and Cache Invalidation at the network cache level.

We have a [hosting guide](./network-cache.md#hosting-guide) for hosts that are interested in providing support.
Binary file added docs/images/enable-graphql-tracing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/graphiql-execute-first-query.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/graphql-query-updated-data.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/quick-edit-post-title.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Installation and Activation

In this guide you will find information about installing and activating the WPGraphQL Smart Cache plugin.

## Requirements

### A WordPress Install

WPGraphQL Smart Cache is a WordPress plugin. You will need a WordPress install that you have access to upload and activate plugins to.

You can test many of the features of the plugin in a local WordPress install using tools such as [LocalWP](https://localwp.com/), but the [Network Cache](./network-cache.md) feature requires a WordPress install on a [supported host](./network-cache.md#supported-hosts).

### WPGraphQL

In order to use the WPGraphQL Smart Cache plugin, you will need to have a WordPress install with the latest version of [WPGraphQL](https://github.com/wp-graphql/wp-graphql/releases) installed and activated.

Over time we plan to support multiple versions, but currently we will only provide support if you're on the latest version of WPGraphQL and WPGraphQL Smart Cache.

## Download the plugin

At the moment, WPGraphQL Smart Cache is not available on the WordPress.org repository, or packagist.org, so you must download the plugin from Github.

You can find the latest release by visiting this page: [https://github.com/wp-graphql/wp-graphql-smart-cache/releases/latest](https://github.com/wp-graphql/wp-graphql-smart-cache/releases/latest).

On this page you will see an "Assets" panel.

The asset named `wp-graphql-smart-cache.zip` is the plugin.

Download the .zip file.

## Upload the Plugin

Login to the WordPress installation you want to install the plugin to.

Upload the .zip to your WordPress installation under "Plugins > Add New".

> **NOTE:** Make sure the .zip file is named `wp-graphql-smart-cache.zip` when you upload it. If you've downloaded the asset multiple times you might have files named wp-graphql-smart-cache (1).zip or similar, and that _can_ be a source of problems.
If you're updating from another version, when you upload the .zip, WordPress will ask if you want to replace the existing plugin. Confirm that you want to.

Activate the plugin.

## Verify the Plugin is Active

The easiest way to confirm the plugin is active is to visit the "WPGraphQL > Settings" page in your WordPress dashboard.

On this page, you should now see 2 new settings Tabs: "Saved Queries" and "Cache".

These settings pages are added by the WPGraphQL Smart Cache plugin.

How these settings work are covered in the following guides:

- [Network Cache](./network-cache.md)
- [Object Cache](./object-cache.md)
- [Persisted Queries](./persisted-queries.md)

----

## 👉 Next Steps

Once the plugin is installed and activated, head back to the [quick start](../README.md#quick-start) or learn more about the plugin features:

- [Network Cache (requires a supported host)](./network-cache.md)
- [Object Cache](./object-cache.md)
- [Persisted Queries](./persisted-queries)
- [Cache Invalidation](./cache-invalidation.md)
186 changes: 186 additions & 0 deletions docs/network-cache.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# Network Cache

- [Quick Start](#quick-start)
- [Supported Hosts](#supported-hosts)
- [How WPGraphQL Network Cache works?](#how-wpgraphql-network-cache-works)
- [Settings](#settings)
- [Purging Caches](#purging-caches)
- [Troubleshooting](#troubleshooting)
- [Hosting Guide](#hosting-guide)

----

## 🚀 Quick Start

This is the Quick Start guide to show the benefits of WPGraphQL Network Cache & Cache Invalidation.

**NOTE:**

Network Cache requires your WordPress instance to be on a [supported host](#supported-hosts).

As more hosts work with us to support this feature, some nuances (for example header responses) in this guide might be different from host to host.

To follow this quick start guide, we recommend having a WordPress install on WP Engine. You can [sign up for a FREE WP Engine Atlas sandbox account](https://wpengine.com/atlas) to follow this guide.

### 👩‍💻 Execute a GraphQL Query (as an HTTP GET request)

Using a browser that is not authenticated to your WordPress site (or an incognito window), execute a GraphQL query as an HTTP GET request by visiting a url for a GraphQL query in the browser, like so (replacing the domain with your domain): `https://${yourdomain.com}/graphql?query={posts{nodes{id,title,uri}}}`

### 🧐 Inspect the Headers

Inspect the headers using your browser developer tools Network tab.

See an `x-cache` header with either a `MISS` value or a `Hit: #` value. The hit is the number of times the cached response has been served. The cache hits are returned from the network cache layer, instead of executing in WordPress.

Refresh the browser a few times and see the `x-cache: Hit: #` count increase.

### 📝 Edit Some Content

In another browser (or incognito window), login to your WordPress dashboard.

Edit the title of your most recent post (add a period to the title, for example) and click update.

### 🥳 Verify the Cache was Purged

Refresh the browser tab with the query and inspect the headers and the JSON response.

The response should have your updated title, and the `x-cache` header should be a `MISS`.

You just witnessed the power of WPGraphQL Smart Cache!

GraphQL responses are served from a cache and WPGraphQL Smart Cache tracks events (publishing, updating, deleting content, etc) and purges appropriate cache(s) in response to said events!

### 💸 Profit

To learn more about the plugin, continue reading the docs below.

----

----

## Supported Hosts



----

## How WPGraphQL Network Cache works

- entire queries are cached by the Host's network cache layer (varnish, etc)
- cached documents are tagged with the values of the x-graphql-keys header
- future requests will be served from the cache, preventing WordPress from loading
- listen to events and call purge( $key_name )
- documents tagged with the key name being purged will be evicted from the network cache
- next request will be a cache miss

For many years, managed WordPress hosts have sped up WordPress by using network-level page caching and serving WordPress pages to users from a cache, preventing the WordPress application itself from being executed to build the page for most requests.

For example, when you host your WordPress website with [WP Engine](https://wpengine.com/atlas), when a visitor visits your website, the first visitor will execute WordPress to build the page, then the page is stored in Varnish cache and subsequent users are served the cached page and WordPress itself is not loaded for those users.

WPGraphQL Smart Cache was built to work in environments that have a network caching layer that caches requests via URL.

Hosts might have to make changes to their environment to fully work with WPGraphQL Smart Cache. We have a hosting guide

Below, we’ll look at how WPGraphQL Smart Cache works with network caching layers.

Because the network cache & cache invalidation strategy requires specific implementation by the host, network caching + invalidation will currently only work on [supported hosts](#supported-hosts).

## GET Requests

To benefit the most from WPGraphQL Smart Cache, you will want to use HTTP GET requests when fetching public data, and you will need to be on a [supported WordPress host](#supported-hosts) such as [WP Engine](https://wpengine.com/atlas).

When making HTTP GET requests to the WPGraphQL Endpoint, the first request for a particular query will be a Cache Miss in the network cache and will be passed to WordPress for execution.

The response will be cached and subsequent requests for the same query (from any client) will be served from teh cache and the WordPress server won't be loaded or tasked with executing.

This significantly reduces the load on your WordPress server, and significantly increases the speed of the API responses.

### GET Requests In Action

Visit the following URL in your browser: [https://content.wpgraphql.com/graphql?query={posts{nodes{id,title}}}](https://content.wpgraphql.com/graphql?query={posts{nodes{id,title}}})

If you inspect the "Network" tab in your browser's developer tools, you should see either an `X-Cache: MISS` header or a `X-Cache: Hit #` header, showing the number of times this query has been served from cache.

**X-Cache: MISS**

Below is a screenshot of a Cache Miss. Here, we see the `x-cache: MISS` header.

This means the request was passed through the network cache to WordPress for execution.

The total response time for the cache miss was ~520ms.

![Screenshot showing a cache miss in the network panel](./docs/images/x-cache-miss.png)

**X-Cache: HIT 26**

After refreshing the browser 26 times, I now see the header `x-cache: HIT 26`.

This means that the request was served from the network cache (in this case Varnish) and was not passed through to WordPress for execution.

This means that the WordPress server didn't experience any load from the 26 refreshes.

Your results may vary, but for me, the total response time for the cache hit was ~110ms, nearly 5x faster than the cache miss!

_Ideally, we'll be able to work with hosts to serve these cache hits even faster!_

![Screenshot showing a cache hit in the network panel](./docs/images/x-cache-hit.png)

### GET Query String Limitations?

One concern you might have with making GraphQL requests via HTTP GET is limitations around Query String Length.

GraphQL Queries can get quite long, so it's easy to push up against [max query string length limitations](https://stackoverflow.com/questions/812925/what-is-the-maximum-possible-length-of-a-query-string#answer-812962).

This takes us to the topic of "Persisted Queries", a feature bundled with the WPGraphQL Smart Cache plugin.


----

## Settings

- max age

----

## Purging Caches

----

## Troubleshooting

- how to identify if the request is served from network cache (inspect headers)
- customizing the headers (limiting when to tag/invalidate)
- skipped types headers (big queries with a lot of nodes)


----

## Hosting Guide

This guide is intended to help WordPress hosts support caching and cache invalidation of WPGraphQL Queries at the network cache level.

Each host will likely have its own stack and opinionated implementations so this guide won't prescribe specific implementation details, but will explain concepts that hosts can use to apply to their hosting environment.

In this guide we'll cover the following topics to have your hosting environment work well with WPGraphQL Smart Cache:

- [Caching WPGraphQL Responses](#caching-responses)
- [Purging Documents](#purging-caches)

### Caching Responses

When GraphQL queries are executed over HTTP GET, the network cache layer should cache the document.

The cache should include query parameters, such as: `query`, `variables` and `operationName`.

Making the same query multiple times should return a cached response until an event purges the cache, or the cache expires based on the Max Age header.

### Tagging Cached Documents

The cached document should be "tagged" using the values returned by the `x-graphql-keys` header.

### Purging Caches

WPGraphQL Smart Cache tracks events and sends out "purge" actions.

The network cache layer should respond to calls of the purge action and purge any cached document(s) tagged with the key being purged.

Loading

0 comments on commit 48b5654

Please sign in to comment.