REST API: Avoid unnecessarily preparing item links.

Do not call the `prepare_links` methods in core REST API controllers, unless the `_links` or `_embedded` fields are requested. There is no need to prepare links if they are never returned in the response. This saves resources, as many calls to `prepare_links` methods perform database queries. 

Props Spacedmonkey, timothyblynjacobs, rachelbaker, desrosj, dlh, hellofromTonya.
Fixes #52992.
Built from https://develop.svn.wordpress.org/trunk@53760


git-svn-id: http://core.svn.wordpress.org/trunk@53319 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
spacedmonkey 2022-07-22 14:00:12 +00:00
parent ee12e8acc0
commit 16dfb05173
22 changed files with 119 additions and 56 deletions

View File

@ -610,6 +610,8 @@ class WP_REST_Application_Passwords_Controller extends WP_REST_Controller {
return $user;
}
$fields = $this->get_fields_for_response( $request );
$prepared = array(
'uuid' => $item['uuid'],
'app_id' => empty( $item['app_id'] ) ? '' : $item['app_id'],
@ -627,7 +629,10 @@ class WP_REST_Application_Passwords_Controller extends WP_REST_Controller {
$prepared = $this->filter_response_by_context( $prepared, $request['context'] );
$response = new WP_REST_Response( $prepared );
$response->add_links( $this->prepare_links( $user, $item ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $user, $item ) );
}
/**
* Filters the REST API response for an application password.

View File

@ -119,6 +119,8 @@ class WP_REST_Block_Directory_Controller extends WP_REST_Controller {
// Restores the more descriptive, specific name for use within this method.
$plugin = $item;
$fields = $this->get_fields_for_response( $request );
// There might be multiple blocks in a plugin. Only the first block is mapped.
$block_data = reset( $plugin['blocks'] );
@ -146,7 +148,10 @@ class WP_REST_Block_Directory_Controller extends WP_REST_Controller {
$this->add_additional_fields_to_object( $block, $request );
$response = new WP_REST_Response( $block );
$response->add_links( $this->prepare_links( $plugin ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $plugin ) );
}
return $response;
}

View File

@ -306,7 +306,9 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $block_type ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $block_type ) );
}
/**
* Filters a block type returned from the REST API.

View File

@ -1119,7 +1119,9 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
// Wrap the data in a response object.
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $comment ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $comment ) );
}
/**
* Filters a comment returned from the REST API.

View File

@ -581,6 +581,18 @@ abstract class WP_REST_Controller {
$fields = array_keys( $properties );
/*
* '_links' and '_embedded' are not typically part of the item schema,
* but they can be specified in '_fields', so they are added here as a
* convenience for checking with rest_is_field_included().
*/
$fields[] = '_links';
if ( $request->has_param( '_embed' ) ) {
$fields[] = '_embedded';
}
$fields = array_unique( $fields );
if ( ! isset( $request['_fields'] ) ) {
return $fields;
}

View File

@ -392,13 +392,15 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller {
// Wrap the data in a response object.
$response = rest_ensure_response( $data );
$links = $this->prepare_links( $post->ID );
$response->add_links( $links );
if ( ! empty( $links['self']['href'] ) ) {
$actions = $this->get_available_actions();
$self = $links['self']['href'];
foreach ( $actions as $rel ) {
$response->add_link( $rel, $self );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = $this->prepare_links( $post->ID );
$response->add_links( $links );
if ( ! empty( $links['self']['href'] ) ) {
$actions = $this->get_available_actions();
$self = $links['self']['href'];
foreach ( $actions as $rel ) {
$response->add_link( $rel, $self );
}
}
}
@ -590,13 +592,14 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller {
$response = rest_ensure_response( $data );
$links = array(
'self' => array(
'href' => rest_url( sprintf( '%s/%s/themes/%s', $this->namespace, $this->rest_base, $request['stylesheet'] ) ),
),
);
$response->add_links( $links );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = array(
'self' => array(
'href' => rest_url( sprintf( '%s/%s/themes/%s', $this->namespace, $this->rest_base, $request['stylesheet'] ) ),
),
);
$response->add_links( $links );
}
return $response;
}

View File

@ -610,16 +610,18 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
// Wrap the data in a response object.
$response = rest_ensure_response( $data );
$links = $this->prepare_links( $item );
$response->add_links( $links );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = $this->prepare_links( $item );
$response->add_links( $links );
if ( ! empty( $links['self']['href'] ) ) {
$actions = $this->get_available_actions( $item, $request );
if ( ! empty( $links['self']['href'] ) ) {
$actions = $this->get_available_actions( $item, $request );
$self = $links['self']['href'];
$self = $links['self']['href'];
foreach ( $actions as $rel ) {
$response->add_link( $rel, $self );
foreach ( $actions as $rel ) {
$response->add_link( $rel, $self );
}
}
}

View File

@ -193,7 +193,9 @@ class WP_REST_Menu_Locations_Controller extends WP_REST_Controller {
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $location ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $location ) );
}
/**
* Filters menu location data returned from the REST API.

View File

@ -134,7 +134,10 @@ class WP_REST_Menus_Controller extends WP_REST_Terms_Controller {
$data = $this->filter_response_by_context( $data, $context );
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $term ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $term ) );
}
/** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */
return apply_filters( "rest_prepare_{$this->taxonomy}", $response, $term, $request );

View File

@ -576,6 +576,8 @@ class WP_REST_Plugins_Controller extends WP_REST_Controller {
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function prepare_item_for_response( $item, $request ) {
$fields = $this->get_fields_for_response( $request );
$item = _get_plugin_data_markup_translate( $item['_file'], $item, false );
$marked = _get_plugin_data_markup_translate( $item['_file'], $item, true );
@ -600,7 +602,10 @@ class WP_REST_Plugins_Controller extends WP_REST_Controller {
$data = $this->add_additional_fields_to_object( $data, $request );
$response = new WP_REST_Response( $data );
$response->add_links( $this->prepare_links( $item ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $item ) );
}
/**
* Filters plugin data for a REST API response.

View File

@ -244,7 +244,9 @@ class WP_REST_Post_Types_Controller extends WP_REST_Controller {
// Wrap the data in a response object.
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $post_type ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $post_type ) );
}
/**
* Filters a post type returned from the REST API.

View File

@ -1933,16 +1933,18 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
// Wrap the data in a response object.
$response = rest_ensure_response( $data );
$links = $this->prepare_links( $post );
$response->add_links( $links );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = $this->prepare_links( $post );
$response->add_links( $links );
if ( ! empty( $links['self']['href'] ) ) {
$actions = $this->get_available_actions( $post, $request );
if ( ! empty( $links['self']['href'] ) ) {
$actions = $this->get_available_actions( $post, $request );
$self = $links['self']['href'];
$self = $links['self']['href'];
foreach ( $actions as $rel ) {
$response->add_link( $rel, $self );
foreach ( $actions as $rel ) {
$response->add_link( $rel, $self );
}
}
}

View File

@ -210,11 +210,13 @@ class WP_REST_Search_Controller extends WP_REST_Controller {
$response = rest_ensure_response( $data );
$links = $handler->prepare_item_links( $item_id );
$links['collection'] = array(
'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
);
$response->add_links( $links );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = $handler->prepare_item_links( $item_id );
$links['collection'] = array(
'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
);
$response->add_links( $links );
}
return $response;
}

View File

@ -368,7 +368,9 @@ class WP_REST_Sidebars_Controller extends WP_REST_Controller {
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $sidebar ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $sidebar ) );
}
/**
* Filters the REST API response for a sidebar.

View File

@ -272,7 +272,9 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller {
// Wrap the data in a response object.
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $taxonomy ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $taxonomy ) );
}
/**
* Filters a taxonomy returned from the REST API.

View File

@ -662,13 +662,15 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
// Wrap the data in a response object.
$response = rest_ensure_response( $data );
$links = $this->prepare_links( $template->id );
$response->add_links( $links );
if ( ! empty( $links['self']['href'] ) ) {
$actions = $this->get_available_actions();
$self = $links['self']['href'];
foreach ( $actions as $rel ) {
$response->add_link( $rel, $self );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = $this->prepare_links( $template->id );
$response->add_links( $links );
if ( ! empty( $links['self']['href'] ) ) {
$actions = $this->get_available_actions();
$self = $links['self']['href'];
foreach ( $actions as $rel ) {
$response->add_link( $rel, $self );
}
}
}

View File

@ -859,7 +859,9 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $item ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $item ) );
}
/**
* Filters the term data for a REST API response.

View File

@ -331,7 +331,9 @@ class WP_REST_Themes_Controller extends WP_REST_Controller {
// Wrap the data in a response object.
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $theme ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $theme ) );
}
/**
* Filters theme data returned from the REST API.

View File

@ -1072,7 +1072,9 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
// Wrap the data in a response object.
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $user ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $user ) );
}
/**
* Filters user data returned from the REST API.

View File

@ -335,7 +335,9 @@ class WP_REST_Widget_Types_Controller extends WP_REST_Controller {
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $widget_type ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $widget_type ) );
}
/**
* Filters the REST API response for a widget type.

View File

@ -726,7 +726,9 @@ class WP_REST_Widgets_Controller extends WP_REST_Controller {
$response = rest_ensure_response( $prepared );
$response->add_links( $this->prepare_links( $prepared ) );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $prepared ) );
}
/**
* Filters the REST API response for a widget.

View File

@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.1-alpha-53759';
$wp_version = '6.1-alpha-53760';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.