REST API: Support nested _fields in revisions controller#11230
REST API: Support nested _fields in revisions controller#11230ellatrix wants to merge 1 commit intoWordPress:trunkfrom
Conversation
Use rest_is_field_included() instead of in_array() for content, title, excerpt, and guid fields in WP_REST_Revisions_Controller. This enables clients to request individual sub-fields (e.g. content.raw without content.rendered) via the _fields parameter, avoiding expensive server-side rendering when only raw data is needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
andrewserong
left a comment
There was a problem hiding this comment.
This change seems sound to me! As mentioned in the linked Gutenberg issue, the performance benefits of skipping the rendered fields makes this very much worthwhile 👍
Totally optional as I don't think we're testing this specifically in the posts controller, but if you wanted you could possibly add a test for the nested properties case? E.g. something like:
/**
* Tests that nested _fields are supported for revision responses.
*
* @ticket 64844
*/
public function test_prepare_item_with_nested_fields() {
wp_set_current_user( self::$editor_id );
$endpoint = new WP_REST_Revisions_Controller( 'post' );
$request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 );
$request->set_param( 'context', 'edit' );
$request->set_param( '_fields', 'title.raw,content.raw' );
$revision = get_post( $this->revision_id1 );
$response = $endpoint->prepare_item_for_response( $revision, $request );
$data = $response->get_data();
// Only the requested sub-fields should be present.
$this->assertArrayHasKey( 'raw', $data['title'] );
$this->assertArrayNotHasKey( 'rendered', $data['title'] );
$this->assertArrayHasKey( 'raw', $data['content'] );
$this->assertArrayNotHasKey( 'rendered', $data['content'] );
}Or, update the existing test_prepare_item_limit_fields test to include the sub-properties:
wordpress-develop/tests/phpunit/tests/rest-api/rest-revisions-controller.php
Lines 508 to 523 in ed2f2ec
In any case, this LGTM!
| $data['slug'] = $post->post_name; | ||
| } | ||
|
|
||
| if ( in_array( 'guid', $fields, true ) ) { |
There was a problem hiding this comment.
Previously, if guid was included, the response always contained both guid.rendered and guid.raw.
Now, if the we requests only guid (but not guid.raw or guid.rendered), they’ll get guid: [] (empty array).
Does this break BC?
There was a problem hiding this comment.
It'll actually wind up including both, due to how rest_is_field_included works internally. Take a look here:
wordpress-develop/src/wp-includes/rest-api.php
Lines 1008 to 1023 in 1f333db
It's pretty neat — if a user just provides the parent guid then the sub-properties will also be matched.
|
Thanks for the review! I'm going to leave it as-is since we're close to Beta 5. |
Use `rest_is_field_included()` instead of `in_array()` for `content`, `title`, `excerpt`, and `guid` fields in `WP_REST_Revisions_Controller`. This lets clients request specific sub-fields (e.g. `_fields=content.raw`) and skip expensive `the_content` rendering. The [REST API `_fields` documentation](https://developer.wordpress.org/rest-api/using-the-rest-api/global-parameters/#_fields) states that nested fields are supported using dot notation. However, the revisions controller uses `in_array()` which doesn't match nested keys like `content.raw`. Developed in: #11230. Props ellatrix, andrewserong, mukeshpanchal27. Fixes #64844. git-svn-id: https://develop.svn.wordpress.org/trunk@61987 602fd350-edb4-49c9-b593-d223f7449a82
Use `rest_is_field_included()` instead of `in_array()` for `content`, `title`, `excerpt`, and `guid` fields in `WP_REST_Revisions_Controller`. This lets clients request specific sub-fields (e.g. `_fields=content.raw`) and skip expensive `the_content` rendering. The [REST API `_fields` documentation](https://developer.wordpress.org/rest-api/using-the-rest-api/global-parameters/#_fields) states that nested fields are supported using dot notation. However, the revisions controller uses `in_array()` which doesn't match nested keys like `content.raw`. Developed in: WordPress/wordpress-develop#11230. Props ellatrix, andrewserong, mukeshpanchal27. Fixes #64844. Built from https://develop.svn.wordpress.org/trunk@61987 git-svn-id: http://core.svn.wordpress.org/trunk@61269 1a063a9b-81f0-0310-95a4-ce76da25c4cd
https://core.trac.wordpress.org/ticket/64844
Use
rest_is_field_included()instead ofin_array()forcontent,title,excerpt, andguidfields inWP_REST_Revisions_Controller. This lets clients request specific sub-fields (e.g._fields=content.raw) and skip expensivethe_contentrendering.The REST API
_fieldsdocumentation states that nested fields are supported using dot notation. However, the revisions controller usesin_array()which doesn't match nested keys likecontent.raw.Several other controllers already use
rest_is_field_included()forraw/renderedsub-fields:WP_REST_Posts_Controller—title.raw,title.rendered,content.raw,content.renderedWP_REST_Templates_Controller—content.raw,title.raw,title.renderedWP_REST_Menu_Items_Controller—title.raw,title.renderedWP_REST_Global_Styles_Controller—title.raw,title.renderedWP_REST_Themes_Controller— generic{field}.raw,{field}.renderedRelated Gutenberg PR: WordPress/gutenberg#76347