Repository navigation
REST API: Let routes turn off _fields, _embed and response links - #14671
jorgefilipecosta wants to merge 3 commits into
Conversation
…nks. Add the `allow_fields`, `allow_embed` and `allow_links` route and handler options. When an option is false, the `_fields` parameter does not filter the response data, the `_embed` parameter does not embed linked resources, or the response links are not added to the response data as `_links`. A handler option takes precedence over the route option, as with `allow_batch`. This lets a route serve its response data as returned, for example data that follows a schema of its own or that is not an array. See #66267.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. 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. Props Bot commandsYou can trigger Props Bot actions by commenting on this PR:
|
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
|
Thanks for picking this up so quickly, @jorgefilipecosta! The opt-out works well, and all checks pass on my side. I spent some time going back and forth with Claude and Codex on the API shape, trying to find the easiest contract to use. Here's where I ended up. What if we combine the three options into one // Turn off all processing.
'response_processing' => false,
// Or turn off only some parts.
'response_processing' => array(
'fields' => false,
'embed' => false,
'links' => false,
),How it could work
Where it should apply
Nice to have
That gives abilities a simple "keep my data as is" switch, and other routes can still turn off single features. Happy to help with any of it! |
|
Hi @gziolo,
I think it does not need an option. It only wraps the response in |
_fields, _embed and response links_fields, _embed and response links
c93e5de to
b6af13a
Compare
Replace the `allow_fields`, `allow_embed` and `allow_links` options with one `response_processing` route and handler option. It is `false` to serve the response data as returned, or an array with `fields`, `embed` and `links` keys to turn off single features: the `_fields` parameter filtering the data, the `_embed` parameter embedding linked resources, and the response links being added to the data as `_links`. Each feature resolves on its own, the handler setting over the route setting, and `embed` is off whenever `links` is off. The settings are resolved once, when the request is matched, and are read from the request attributes and the matched handler by the server, by `rest_filter_response_fields()` and by `WP_REST_Controller::get_fields_for_response()`. A response returned by the `rest_pre_dispatch` filter follows the settings of the route it was returned for. The index lists the settings of an endpoint that turns off a feature, and `rest_preload_api_request()` no longer casts the data to an array. See #66267.
b6af13a to
8548db3
Compare
gziolo
left a comment
There was a problem hiding this comment.
Thanks so much, @jorgefilipecosta, for working through all the feedback so carefully! The single response_processing option is simple to use, and it covers everything we discussed: controller field selection, cached responses, preloading, the index, and data that is not an array. Your answer about _envelope makes sense to me too. I left one small inline suggestion about ArrayAccess data to consider before this lands. This is ready from my side. 🚀
8548db3 to
7ec8c2f
Compare
`rest_filter_response_fields()` leaves the response unchanged when its data is not an array, and keeps list items that are not arrays. `WP_REST_Server::response_to_data()` returns scalar and object data as it is instead of adding links to it, and leaves list items that are not arrays alone when embedding. Routes that return such data no longer need the `response_processing` option to avoid type errors. See #66267.
7ec8c2f to
ba8e2f3
Compare
Follow up to #14547 (comment).
This PR adds the
response_processingroute and handler option, which lets a route serve its response data as returned:fields: when false, the_fieldsparameter does not filter the response data, inrest_filter_response_fields()and inWP_REST_Controller::get_fields_for_response().embed: when false, the_embedparameter does not embed linked resources. The links are still added as_links.links: when false, the response links are not added to the response data as_links. Embedding needs the links, soembedis off too.Every feature is on by default. Each one resolves on its own: the handler setting applies first, then the route setting, as with
allow_batch. The option covers these three features only. Authentication, permission checks, status codes, headers, JSON encoding and_envelopework as before, and keys of the data itself, such as its own_links, stay as returned.The settings are resolved once, when the request is matched, by
WP_REST_Server::resolve_response_processing(). They are then read from the request attributes and the matched handler, so controllers can read them with$request->get_attributes().WP_REST_Server::get_response_processing()returns them for a request, and matches the request to its route when the response came from therest_pre_dispatchfilter, so cached responses follow the same settings. OPTIONS requests are served the route description, so every feature is on for them. They apply to served, enveloped, batched and preloaded requests, andrest_preload_api_request()no longer casts the data to an array. The index lists the settings of an endpoint that turns off a feature.The second commit serves data that is not an array as returned even without the option:
rest_filter_response_fields()leaves scalars and objects alone and keeps list items that are not arrays, andWP_REST_Server::response_to_data()does not add links to them, unless the object implementsArrayAccess, and leaves list items that are not arrays alone when embedding.This lets a route return its data unchanged, e.g. the abilities run endpoint, whose result follows the ability's output schema and can be an object, a list or a scalar value. #14547 uses the option for that endpoint.
Drafted with AI assistance and reviewed by me.
Trac ticket: https://core.trac.wordpress.org/ticket/66267
Testing
Verify unit tests are passing: