Opened 5 years ago
Last modified 14 months ago
#50012 new defect (bug)
REST API: Fields filter does not work with "object" collection responses
Reported by: | TimothyBlynJacobs | Owned by: | |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | normal | Version: | 4.8 |
Component: | REST API | Keywords: | has-patch needs-testing |
Focuses: | Cc: |
Description
As reported in #core-restapi, trying to use the _fields
parameter with the wp/v2/taxonomies
route does not return the expected result. Instead, an empty set is returned.
http://trunk.test/wp-json/wp/v2/taxonomies?_fields=name
Looking into it, this happens with both the taxonomies
and types
route because they return an "object" collection response. That is, instead of returning an array, they return an object keyed by the taxonomy or post type slug.
{ "category": { "name": "Categories", "slug": "category" } }
instead of...
[ { "name": "Categories", "slug": "category" } ]
This means that the wp_is_numeric_array
check in rest_filter_response_fields
to try and determine whether this is a collection response fails and it treats the response as a single object, and then ends up removing all the properties.
It appears that the _fields
check inside of the controller itself work, it is just the "fallback" filtering that doesn't work and ends up corrupting the response.
A possible fix would be to somehow mark that a response has already been filtered, and rest_filter_response_fields
does not need to be run. This would probably also be a performance benefit.
Trac ticket: https://core.trac.wordpress.org/ticket/50012
This fixes support for the
_fields
parameter in REST requests for taxonomies and post types. These REST responses take the form of objects rather than arrays -- e.g.{ category: { ...data }, post_tag: { ...data } }
-- and the_fields
filter was being applied to that final data set, filtering out the top-level items.The
_fields
parameter is also applied earlier in theget_items
logic to the nested objects themselves. This fix removes_fields
from the request after that occurs and before the final response is processed.### Alternatives
One alternative option is here: https://github.com/johnwatkins0/wordpress-develop/commit/b81852609627f32bd841754d005ccbea68495053 This adds a couple of new methods to the WP_REST_Request class. Another possibility I looked at was adding a filter at the beginning
rest_filter_response_fields
and adding a filter callback in the endpoint classes that have the nested object structure. But both those options do essentially the same thing as this PR with much more code.The drawback to this approach is it doesn't automatically apply to new endpoints that have similar structures, but the other approaches I thought of don't either. It might be worth exploring an option in
register_rest_route
or somewhere similar to indicate thatget_items
for a given endpoint returns an object rather than an array and_fields
filtering should not be applied to the final object, but I also think anyone building custom endpoints at this level can figure out their own workarounds.