#61739 closed enhancement (fixed)
REST API: Implement 'targetHints' property
Reported by: |
|
Owned by: |
|
---|---|---|---|
Milestone: | 6.7 | Priority: | normal |
Severity: | normal | Version: | |
Component: | REST API | Keywords: | has-patch has-unit-tests |
Focuses: | rest-api | Cc: |
Description
A proposal to add the targetHints
property to the link description object as part of the self
link. The current ticket will only cover the allow
header reference.
Originally suggested in https://core.trac.wordpress.org/ticket/50388#comment:6.
Why?
Consumers who render a list of posts and CRUD actions related to each item must make a separate OPTIONS
request to check if the user has permission to perform these actions.
The N+1 requests affect the performance on the client and the server.
Example targetHints
property:
{ "_links": { "self": [ { "href": "https://api.w.org/wp-json/wp-json/wp/v2/pages/1", "targetHints": { "allow": [ "GET", "POST", "PUT", "DELETE" ] } } ] } }
Change History (12)
This ticket was mentioned in Slack in #core-editor by mamaduka. View the logs.
9 months ago
This ticket was mentioned in PR #7139 on WordPress/wordpress-develop by @TimothyBlynJacobs.
9 months ago
#4
- Keywords has-patch has-unit-tests added; needs-patch needs-unit-tests removed
This needs to be refactored to be less ugly, and handle errors from WP_REST_Request::from_url
. But this is my thinking on how we could automatically add a targetHint.
Trac ticket: [](https://core.trac.wordpress.org/ticket/61739)
#5
@
8 months ago
- Milestone changed from Awaiting Review to 6.7
This needs to be in the WP 6.7 milestone.
Here's the improvement we're shipping on the editor side - https://github.com/WordPress/gutenberg/pull/64504.
@noisysocks commented on PR #7139:
8 months ago
#6
@TimothyBJacobs: How's this going? It's marked as a backport for 6.7. Beta 1 is 4 weeks and I'll sync packages in just over 2 weeks.
@TimothyBlynJacobs commented on PR #7139:
8 months ago
#7
Refreshed with the latest changes from GB. I'll leave it open a few days for feedback.
#8
@
7 months ago
- Owner set to TimothyBlynJacobs
- Resolution set to fixed
- Status changed from new to closed
In 59032:
@TimothyBlynJacobs commented on PR #7139:
7 months ago
#9
Merged in r59032.
@freibergergarcia commented on PR #7139:
4 months ago
#10
@TimothyBJacobs @swissspidy I would like to validate something about this change.
The change impacts performance depending on the number of users, posts, and how you hit the users endpoint.
When rest_send_allow_header
is called from get_target_hints_for_link
it ends up calling the user's permission callback: https://github.com/WordPress/wordpress-develop/blob/trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php#L458 and count_user_posts( $user->ID, $types )
for each user.
Depending on the number of $types
and data (users, posts), this call can be expensive. An example could be: /wp-json/wp/v2/users?per_page=x&pagination=true&page=1
. The higher per_page
is set, the worse it performs.
Questions:
- what's the best way to "disable" it?
- is there a different way to implement this without having to call
count_user_posts
- have you considered the performance implications?
- does it need to be "enabled" by default?
One alternative to work around this is the following. Do you think it's the most appropriate way?
/**
* Add targetHints to the self-links in the user response to prevent COUNT slow queries.
*
* @see get_target_hints_for_link core method in WordPress version 6.7
*/
add_filter( 'rest_prepare_user', function( $response, $user, $request ) {
$links = $response->get_links();
if ( empty( $links ) ) {
return $response;
}
$response->remove_link('self');
foreach( $links as $rel => $set ) {
if ( 'self' !== $rel ) {
continue;
}
foreach( $set as $link ) {
if ( ! isset( $link['href'] ) ) {
continue;
}
$response->add_link(
$rel,
$link['href'],
array_merge(
$link['attributes'] ?? [],
[
'targetHints' => [
'allow' => [],
]
]
)
);
}
}
return $response;
}, 10, 3 );
I'm looking forward to hearing your thoughts on this.
@swissspidy commented on PR #7139:
4 months ago
#11
Could you perhaps open a Trac ticket to increase visibility of this?
Would you say that caching count_user_posts
would mostly solve this? There's a ticket for that which would be nice to land: https://core.trac.wordpress.org/ticket/39242
@swissspidy commented on PR #7139:
4 months ago
#12
Actually, looks like https://core.trac.wordpress.org/ticket/46249 seems to basically have covered this case, but was pointed to https://core.trac.wordpress.org/ticket/39242 as well.. So yeah, maybe let's focus on the caching?
Sharing suggestions by @TimothyBlynJacobs, during our 1-on-1 chat: