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; return $user;
} }
$fields = $this->get_fields_for_response( $request );
$prepared = array( $prepared = array(
'uuid' => $item['uuid'], 'uuid' => $item['uuid'],
'app_id' => empty( $item['app_id'] ) ? '' : $item['app_id'], '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'] ); $prepared = $this->filter_response_by_context( $prepared, $request['context'] );
$response = new WP_REST_Response( $prepared ); $response = new WP_REST_Response( $prepared );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $user, $item ) ); $response->add_links( $this->prepare_links( $user, $item ) );
}
/** /**
* Filters the REST API response for an application password. * 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. // Restores the more descriptive, specific name for use within this method.
$plugin = $item; $plugin = $item;
$fields = $this->get_fields_for_response( $request );
// There might be multiple blocks in a plugin. Only the first block is mapped. // There might be multiple blocks in a plugin. Only the first block is mapped.
$block_data = reset( $plugin['blocks'] ); $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 ); $this->add_additional_fields_to_object( $block, $request );
$response = new WP_REST_Response( $block ); $response = new WP_REST_Response( $block );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $plugin ) ); $response->add_links( $this->prepare_links( $plugin ) );
}
return $response; return $response;
} }

View File

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

View File

@ -581,6 +581,18 @@ abstract class WP_REST_Controller {
$fields = array_keys( $properties ); $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'] ) ) { if ( ! isset( $request['_fields'] ) ) {
return $fields; return $fields;
} }

View File

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

View File

@ -610,6 +610,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
// Wrap the data in a response object. // Wrap the data in a response object.
$response = rest_ensure_response( $data ); $response = rest_ensure_response( $data );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = $this->prepare_links( $item ); $links = $this->prepare_links( $item );
$response->add_links( $links ); $response->add_links( $links );
@ -622,6 +623,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
$response->add_link( $rel, $self ); $response->add_link( $rel, $self );
} }
} }
}
/** /**
* Filters the menu item data for a REST API response. * Filters the menu item data for a REST API response.

View File

@ -193,7 +193,9 @@ class WP_REST_Menu_Locations_Controller extends WP_REST_Controller {
$response = rest_ensure_response( $data ); $response = rest_ensure_response( $data );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $location ) ); $response->add_links( $this->prepare_links( $location ) );
}
/** /**
* Filters menu location data returned from the REST API. * 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 ); $data = $this->filter_response_by_context( $data, $context );
$response = rest_ensure_response( $data ); $response = rest_ensure_response( $data );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $term ) ); $response->add_links( $this->prepare_links( $term ) );
}
/** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ /** 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 ); 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. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/ */
public function prepare_item_for_response( $item, $request ) { 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 ); $item = _get_plugin_data_markup_translate( $item['_file'], $item, false );
$marked = _get_plugin_data_markup_translate( $item['_file'], $item, true ); $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 ); $data = $this->add_additional_fields_to_object( $data, $request );
$response = new WP_REST_Response( $data ); $response = new WP_REST_Response( $data );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $item ) ); $response->add_links( $this->prepare_links( $item ) );
}
/** /**
* Filters plugin data for a REST API response. * 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. // Wrap the data in a response object.
$response = rest_ensure_response( $data ); $response = rest_ensure_response( $data );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $post_type ) ); $response->add_links( $this->prepare_links( $post_type ) );
}
/** /**
* Filters a post type returned from the REST API. * Filters a post type returned from the REST API.

View File

@ -1933,6 +1933,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
// Wrap the data in a response object. // Wrap the data in a response object.
$response = rest_ensure_response( $data ); $response = rest_ensure_response( $data );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$links = $this->prepare_links( $post ); $links = $this->prepare_links( $post );
$response->add_links( $links ); $response->add_links( $links );
@ -1945,6 +1946,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
$response->add_link( $rel, $self ); $response->add_link( $rel, $self );
} }
} }
}
/** /**
* Filters the post data for a REST API response. * Filters the post data for a REST API response.

View File

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

View File

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

View File

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

View File

@ -859,7 +859,9 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
$response = rest_ensure_response( $data ); $response = rest_ensure_response( $data );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $item ) ); $response->add_links( $this->prepare_links( $item ) );
}
/** /**
* Filters the term data for a REST API response. * 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. // Wrap the data in a response object.
$response = rest_ensure_response( $data ); $response = rest_ensure_response( $data );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $theme ) ); $response->add_links( $this->prepare_links( $theme ) );
}
/** /**
* Filters theme data returned from the REST API. * 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. // Wrap the data in a response object.
$response = rest_ensure_response( $data ); $response = rest_ensure_response( $data );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $user ) ); $response->add_links( $this->prepare_links( $user ) );
}
/** /**
* Filters user data returned from the REST API. * 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 = rest_ensure_response( $data );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $widget_type ) ); $response->add_links( $this->prepare_links( $widget_type ) );
}
/** /**
* Filters the REST API response for a 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 = rest_ensure_response( $prepared );
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
$response->add_links( $this->prepare_links( $prepared ) ); $response->add_links( $this->prepare_links( $prepared ) );
}
/** /**
* Filters the REST API response for a widget. * Filters the REST API response for a widget.

View File

@ -16,7 +16,7 @@
* *
* @global string $wp_version * @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. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.