Cache REST API endpoints#121
Conversation
|
The main things this is doing right now are:
|
|
There are two main problems left to solve:
I did some searching to see what other plugins have done in this space, but I only came up with 2 small ones, and they're both specifically targeting the REST API. None of the major general-purpose plugins have done this yet. Those two plugins both use transients, so they're not really an effective solution for the type of user who would use a general-purpose caching plugin. Using transients is definitely better than nothing, but unless you have an object cache setup, you're still hitting MySQL. Even if you do have an object cache, you're still hitting PHP and loading all of WP. The approach here should be much faster than that, even if we don't come up with a way to support |
01c1194 to
f7f1536
Compare
|
I rebased the branch into a handful of commits, to make reviewing easier, and to give it a cleaner merge history. I haven't found any problems in my tests, so I think it's ready for review. @kraftbj Do you mind taking a look and giving me any feedback you have? I can see three options for moving forward:
|
|
@kraftbj, any thoughts on the above? |
|
Apologies for the delay. I'll take a look tomorrow. |
| * Need to update the cache when underlying data changes, rather than just waiting for manual expiration? | ||
| * would be bad if deleted post continue to show up in cache, etc | ||
| * how to tell that updating a post or category maps to an API endpoint? | ||
| * worst case, could just flush all endpoint cache files when any post/comment/taxterm/etc is updated |
There was a problem hiding this comment.
I'd like to see if there's a way to determine what we need to clear in a more specific manner. Nuking everything is more conservative but afraid about scaling on really large sites.
There was a problem hiding this comment.
Yeah, that's a good point to bring up. I don't have any ideas for how to map content to API endpoints right now (other than just a hardcoded list for known endpoints like /posts).
One thing that could help avoid scaling issues, would be to keep track of when we flush the cache, and don't do it more often then once every 5 minutes, or something like that. We'll need to do more thinking/testing/etc there, though
There was a problem hiding this comment.
You can check rest_base on the post types, but otherwise there's no generic mapping.
|
I really like it and reads wonderfully. I need to go back through to make sure there's a way to confirm you're being served a cached file; my initial tests didn't have a header or content added to the json, etc to confirm that it's working, clearing, etc. Going to ask Guardians for a second set of eyes too. |
Thanks! That warms my heart :D
Ah, I should have documented what I did. Added that in ca8a37a. |
| */ | ||
| function wpsc_rest_eof_tags( $eof_pattern ) { | ||
| $json_object_pattern = '^[{].*[}]$'; | ||
| $json_collection_pattern = '^[\[].*[\]]$'; |
There was a problem hiding this comment.
Note that null, "hello", and 21345 are all completely valid JSON responses as well, but core wouldn't generate that by default.
There was a problem hiding this comment.
Thanks, I'll add a @todo note about that for future iterations.
76c6068 to
2c57de8
Compare
|
I enabled this on WordCamp.org production so that we can get some real-world testing, and so far things look good. I'll keep an eye on it, though, and push commits for any bugs. |
|
I noticed a problem on production, but it turned out to be #97, so I'll send a PR for that. If |
|
Sorry for the noise but I just want to say that I'm really looking forward to this feature. Especially since the latest version of wordpress includes the rest api by default. |
This has been disabled for awhile, and will be replaced by the dedicated WP Super Cache plugin. See Automattic/wp-super-cache#121 git-svn-id: https://meta.svn.wordpress.org/sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins@3770 74240141-8908-4e6f-9713-ba540dce6ec7
|
I think legacy cache files will the best way of storing REST API calls, especially as now I've merged in code that stores those files in the supercache directories. See #177. They'll store header fields as well as page contents. I think we'll be able to figure out a way to map garbage collection of the "main" supercache directory with the REST API directories that will be created. After all, we'll have post_ids of any posts. I also added wpsc_delete_files and wpsc_rebuild_files functions to somewhat replace prune_super_cache in some situations so those could be entry points for doing the deleting of cached REST API calls. |
|
I think something like the gc_cache action could be used to delete the REST API cache files, but I might need to add a gc_cache_id action - that would pass a post_id rather than a path.. |
340905a to
5eec440
Compare
5eec440 to
21a7396
Compare
21a7396 to
0e1704f
Compare
|
I rebased the PR against In hindsight, those were both probably bad ideas, since any comments on the original commits were lost, and anyone who has a local checkout will need to |
|
@donnchawp, unfortunately I don't think I'll have much more time to devote to this anytime soon, so what do you think about merging the current PR as v1, and then doing the changes in your comments in future iterations? If it'd help, we could keep the plugin off by default, in order to get more testing before it's turned on by default. |
|
I'll test it when I have time. We'll need some sort of garbage collection in there but I don't think it'll be hard to do. I agree, we should try and get a version 1 out there as soon as possible, with the changes to where legacy cache files are stored we could almost call it a version 2.0 :) |
|
I ran into a problem with this branch today, and it's already documented above, but I'd completely forgotten about it, so it's probably worth repeating. Right now the HTTP headers aren't saved and served during cached responses, which can cause bugs in plugins. For example, here's an API response that returns a Cache miss:Cache hitIf there's some code that's checking the status code of the response, it'll correctly get I think this is something that'll need to be fixed before this branch can be merged. It sounds like @donnchawp already has plans for that. |
|
Another blocker for merging that I just realized, is that we need to make sure that API requests that require some form of authentication are never cached. For normal requests, Super Cache relies on WP's cookie auth, which can also be used with the REST API, but the API allows several additional methods -- e.g., OAuth, JSON web tokens, etc -- especially for server-to-server requests. At first glance, it seems like checking for the Authorization header would cover all standards cases. I'm not 100% confident about that, though. There'll still be situations where plugin authors pass tokens in arbitrary To err on the side of caution, it might be good to also avoid caching requests that contain an cc @donnchawp |
Could we maybe checked for an |
|
If there's a current user by the time the response is generated, then some form of authentication has worked. Authentication plugins for the REST API don't do anything special, they just hook into the The |
Are you thinking that it's enough to just check for a current user, rather than checking for both the current user AND the I think checking for |
|
As I said previously, I think we should use legacy cache files to store REST API calls. That may go some way towards taking care of authentication, but serving cache files to authenticated REST API clients might be problematic. The plugin needs to support an authentication key that's plugged into the code that generates wp_cache_key. That code fires way before WordPress authentication happens however. |
|
https://github.com/airesvsg/wp-rest-api-cache/blob/master/class-wp-rest-cache.php does something interesting. It uses rest_pre_dispatch to intercept REST API requests, and then "runs" the request if it's not cached, caches it in a transient option before serving it. It doesn't do any granular maintenance of cache files. |
This has been disabled for awhile, and will be replaced by the dedicated WP Super Cache plugin. See Automattic/wp-super-cache#121 git-svn-id: https://meta.svn.wordpress.org/sites/trunk/wordcamp.org@3770 74240141-8908-4e6f-9713-ba540dce6ec7
This has been disabled for awhile, and will be replaced by the dedicated WP Super Cache plugin. See Automattic/wp-super-cache#121 git-svn-id: https://meta.svn.wordpress.org/sites/trunk/wordcamp.org@3770 74240141-8908-4e6f-9713-ba540dce6ec7 git-svn-id: https://github.com/WordPress/wordcamp.org.git@771 a64dc54a-4538-25e2-d9ce-ce57b7db7bff
This has been disabled for awhile, and will be replaced by the dedicated WP Super Cache plugin. See Automattic/wp-super-cache#121 git-svn-id: http://meta.svn.wordpress.org/sites/trunk/wordcamp.org@3770 74240141-8908-4e6f-9713-ba540dce6ec7
This has been disabled for awhile, and will be replaced by the dedicated WP Super Cache plugin. See Automattic/wp-super-cache#121 git-svn-id: https://meta.svn.wordpress.org/sites/trunk/wordcamp.org@3770 74240141-8908-4e6f-9713-ba540dce6ec7
This has been disabled for awhile, and will be replaced by the dedicated WP Super Cache plugin. See Automattic/wp-super-cache#121 git-svn-id: https://meta.svn.wordpress.org/sites/trunk/wordcamp.org@3770 74240141-8908-4e6f-9713-ba540dce6ec7
|
Quick question: a bit off topic, but what happens if a page does a GET AJAX (JSON) request to the backend? shouldn't JSON support be extended to that case too? |
It depends on Automattic/wp-super-cache#121 in order to work, which hasn't been merged. We used to run that branch of the plugin on production, but stopped doing that several years ago. At that point, this plugin became inactive, and it's no longer doing anything. We have some caching at the Nginx layer in order to prevent overloading the site if the the Tagregator endpoint gets too much traffic, so this is no longer needed anyway.
|
Any update on this? All mobile apps are using REST API to access the content and this should be cached, too. |
|
No update at all. There are other plugins that will cache REST API requests. Someone asked about it on the forum recently. A quick search of the plugins found a few. Have you tried any of them? |
|
Closing since there are other options, and this PR would take a lot of work to become useful. |
This is still a work in progress, but a good chunk of it is there.
I'd love to get some feedback from @donnchawp and @kraftbj. Do you think this is heading in the right direction? Are there any major parts missing? Any other thoughts?
One thing I haven't looked at yet is support for
mod_rewrite, so this is just forlegacyandPHPmodes.