Caching endpoints with query params
-
Hey there,
I was wondering if it’s possible to cache custom endpoints with query parameters.
e.g.
myapi/v1/products?category=apparel
It doesn’t seem to be registering these types of endpoints for me. Is there a particular way to register them for query strings?
Best,
Adam
-
Hi @adamhammad
Thank you for using our plugin. Yes it is possible to cache custom endpoints with query parameters. All you have to do is register your custom endpoint for caching like this:
function wprc_add_custom_endpoint( $allowed_endpoints ) { if ( ! isset( $allowed_endpoints[ 'myapi/v1' ] ) || ! in_array( 'products', $allowed_endpoints[ 'myapi/v1' ] ) ) { $allowed_endpoints[ 'myapi/v1' ][] = 'products'; } return $allowed_endpoints; } add_filter( 'wp_rest_cache/allowed_endpoints', 'wprc_add_custom_endpoint', 10, 1);
If you use query parameters they will be cached as well. So a call to
myapi/v1/products
will result in a different cache than a call tomyapi/v1/products?category=apparel
I hope this answers your question.
Hmm that is how I have it setup. However on some endpoints i get the following on the first request:
<br /> <b>Fatal error</b>: Uncaught Error: Cannot use object of type stdClass as array in /Users/xxxxxxxx/Projects/xxxxxxxx/wp-content/plugins/wp-rest-cache/includes/caching/class-caching.php:714 Stack trace: #0 /Users/xxxxxxxx/Projects/xxxxxxxx/wp-content/plugins/wp-rest-cache/includes/caching/class-caching.php(591): WP_Rest_Cache_Plugin\Includes\Caching\Caching->determine_object_type(Array) #1 /Users/xxxxxxxx/Projects/xxxxxxxx/wp-content/plugins/wp-rest-cache/includes/caching/class-caching.php(130): WP_Rest_Cache_Plugin\Includes\Caching\Caching->register_endpoint_cache('c91289d1c66027e...', Array, '/wp-json/abode/...') #2 /Users/xxxxxxxx/Projects/xxxxxxxx/wp-content/plugins/wp-rest-cache/includes/api/class-endpoint-api.php(153): WP_Rest_Cache_Plugin\Includes\Caching\Caching->set_cache('c91289d1c66027e...', Array, 'endpoint', '/wp-json/abode/...') #3 /Users/xxxxxxxx/Projects/xxxxxxxx/wp-includes/class-wp-hook.php(286): WP_Rest_Cache_Plugin\Includes\API\Endpoint_Api->save_cache(Object(stdClass), Objec in <b>/Users/xxxxxxx/Projects/xxxxxxx/wp-content/plugins/wp-rest-cache/includes/caching/class-caching.php</b> on line <b>714</b><br />
Then i get a cached response after that. However the cache doesn’t appear in Settings > WP REST Cache.
Other endpoints that don’t produce this error do get cached and appear in the settings.
Any ideas on how to debug this?
Okay so i went to the line of the error and realised it was related to checking the Object Type.
Considering this doesn’t really affect the way it works i’ve just added this piece of code in for now above that line.
if(gettype($data['data']) === 'object') { return "Object"; }
-
This reply was modified 6 years ago by
botoxparty.
Hi @adamhammad
Although that piece of code prevents the error from happening, it is not the correct way to solve this problem. The object type is needed for the plugin to have the ability to flush (or delete) caches automatically if the object is edited/deleted in the wp-admin.
So for instance if your endpoint contains the custom post type
products
and there is a cache for product ID = 42 and that product is edited in the wp-admin. The plugin should check for caches with object type = ‘products’ and ID = 42 and flush those. Your code now simply states it is anObject
, which means the plugin will not know it has to flush the cache if the product is edited.(I hope I am making myself clear ?? )
I already have a solution in mind, which I first need to test. So if this indeed solves the problem I will release a fix somewhere in the upcoming days.
Ah okay! I see!
So yep I got this working with one of my custom endpoints which returns a single page.
Looking at this function:
private function determine_object_type( $data ) { if ( array_key_exists( 'id', $data['data'] ) ) { $this->is_single = true; if ( array_key_exists( 'type', $data['data'] ) ) { return $data['data']['type']; } else if ( array_key_exists( 'taxonomy', $data['data'] ) ) { return $data['data']['taxonomy']; } } else { $this->is_single = false; if ( count( $data['data'] ) && isset( $data['data'][0] ) ) { if ( array_key_exists( 'type', $data['data'][0] ) ) { return $data['data'][0]['type']; } else if ( array_key_exists( 'taxonomy', $data['data'][0] ) ) { return $data['data'][0]['taxonomy']; } } } return 'unknown'; }
I made sure I put the page ID in ‘id’, and the ‘type’ in type. This worked successfully when updating the page and clearing the cache.
Also what is the ‘Item API Caches’?
The Item API Caches are caches of a single item from a multi-item endpoint. So for instance the
/wp-json/wp-/v2/posts
contains multiple posts. Now let’s say this endpoint contains the posts with the id’s 1, 2, 3, 4 and 5. Whenever one of these posts is update the endpoint cache for the posts is flushed.
The item caches are caches of the separate posts within that endpoint. This is done so that when for instance the post with id=2 is edited, the posts endpoint is flushed and the item cache for id=2 is also flushed. Now when the posts endpoint is requested again, the posts 1, 3, 4 and 5 are retrieved from the item cache and post 2 is regenerated.This technique however only works for endpoints that use the
WP_REST_Posts_Controller
, theWP_REST_Terms_Controller
or theWP_REST_Attachments_Controller
from the WordPress Core. It doesn’t work for custom endpoints (even not when they extend one of those controllers), because in order for this to work we extend those controllers.Hi @adamhammad
We just released a new version of our plugin which should fix the error you got.
-
This reply was modified 6 years ago by
- The topic ‘Caching endpoints with query params’ is closed to new replies.