Optimizing default WordPress REST API user endpoint for redundant DB calls made for permissions check.

While working with one of our client at rtCamp who was using REST API for thier website with PWA theme, We found out that it was taking way too much time at user endpoint wp/v2/users/{id}

Upon investigation I found out that on server dispatch it goes under permission check with permission_callback per item with following SQL query hitting db several times based on per page items.

SELECT COUNT(*) FROM wp_posts WHERE ( ( post_type = 'post' AND ( post_status = 'publish' ) ) OR ( post_type = 'page' AND ( post_status = 'publish' ) ) OR ( post_type = 'attachment' AND ( post_status = 'publish' ) ) OR ( post_type = 'custom_post_0' AND ( post_status = 'publish' ) ) OR ( post_type = 'custom_post_1' AND ( post_status = 'publish' ) ) OR ( post_type = 'custom_post_2' AND ( post_status = 'publish' ) ) OR ( post_type = 'custom_post_3' AND ( post_status = 'publish' ) ) OR ( post_type = 'custom_post_4' AND ( post_status = 'publish' ) ) ) AND post_author = {id} 

As you can see in snippet below it’s calling for

`permission_callback` => array( $this, 'get_items_permission_callback' )

which has count_user_posts call which is uncached and hits DB every time.

I have worked on few WordPress VIP projects for same reasons I configured My editor ( Netbeans ) to check for WP coding Standards it gives me warning about count_users_posts and asked me to use wpcom_vip_count_user_posts instead because count_users_posts uncached.

So I have to make it’s result cached somehow,

Firstly I Google ( don’t judge me everybody does it. 😀 ) for some solution but found nothing even on 4th search page thats deep web for me .

No help came from stackoverflow which was my only hope that day.

I searched WordPress core trac there is ticket for same  #39242,

finally after some debugging, I decided to replace permission_callback for wp/v2/users/{id} route with cached function with custom code as follows.

The Cached permission callback is similar function as core with only one twist different callback for user post count 😀

The cached_count_users_posts function is clone of WordPress VIP function wpcom_vip_count_user_posts

This will offload your DB hits, it’s will very helpful while handling heavy weight WordPress sites, until that core ticket is answered and closed, I will try to contribute on that core ticket and that should be our the long term plan.

here is full code My Friend, Hope this helps you.

Did you do things differently please let me know in comments ?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.