Changing Responses of Working Endpoints
Sometimes there may be situations where it's necessary to change the responses of already working endpoints. For example, to add or remove data from them. The logic of the WP API allows this to be done without much difficulty.
This guide describes how to add additional data to the responses of endpoints. It also explains how to supplement the _links key and how to create your own compact URL (CURIE) in such a _links key.
Adding Your Field to the REST API Response
Important Note About Changing REST API Responses
Changing response data is dangerous! Adding data to the response is safe!
The API returns many fields in responses, and many of them may not be needed by you. This may lead to the temptation to change or remove fields from REST API responses. However, this should not be done because other Clients expect standard responses. One such Client is the WordPress admin interface itself.
Therefore, changing or removing response data from the WordPress core endpoint is prohibited!
How to change the response if it's really necessary?
If you really need to change some response data, there are several options:
- You can duplicate the field with modified data.
- Or you can create a query parameter that, when specified, will remove unnecessary fields from the response.
- Or you can work with contexts, for example, create your own context that will return only the fields you need.
As you can see, there are many ways to change the response data without harming the overall API functionality, so use them!
There are two functions that allow you to add data (fields) to the REST API response:
- register_rest_field().
- register_meta() and its derivatives:
For more details on how these functions work, read their descriptions and see examples of adding fields below.
Both of these functions are suitable for any REST API resource (post, term ...) and any request method (GET POST).
The disadvantage of register_meta() is that the function only understands scalar values, while register_rest_field() can handle objects.
register_rest_field( $object_type, $attribute, $args )
register_rest_field() adds a custom field for the specified REST API resource.
- $object_type(string/array) (required)
- The name of the REST resource for which the field is registered. Multiple resources can be specified in an array. Possible core resources: post, term, meta, user, comment. It can also be the name of a custom resource, for example when registering a post type or taxonomy.
- $attribute(string) (required)
- The name of the field. This field will be used as a key in the REST response object.
- $args(array)
Parameters for processing the specified field during the REST request.
-
$get_callback(string/array/null)
Function to retrieve the value of the field.
Default: null - the value will not be shown in the response -
$update_callback(string/array/null)
Function used to set and update the value of the field.
Default: null - the value cannot be set or updated - $schema(string/array/null)
Function used to create the schema of this field.
Default: null - the schema will not be shown
Default: array()
-
Example
Let's create the ability to read and write a meta-field in the REST request for comments.
This example shows how to add the karma field to the response for comments. It works based on an existing but unused core field comment_karma in the wp_comments table. Note that the actual implementation of comment_karma should use a separate endpoint.
This is a demonstration example that shows what permission checks or error handling may be required for the field.
// register the field during the 'rest_api_init' event! add_action( 'rest_api_init', function () { // register the REST field register_rest_field( 'comment', 'karma', array( // function to output the field value in the response 'get_callback' => function( $comment_arr ) { $comment_obj = get_comment( $comment_arr['id'] ); return (int) $comment_obj->comment_karma; }, // function to update the field 'update_callback' => function( $karma, $comment_obj ) { $ret = wp_update_comment( array( 'comment_ID' => $comment_obj->comment_ID, 'comment_karma' => $karma ) ); if ( false === $ret ) { return new WP_Error( 'rest_comment_karma_failed', __( 'Failed to update comment karma.' ), array( 'status' => 500 ) ); } return true; }, // description of the field in the schema 'schema' => array( 'description' => __( 'Comment karma.' ), 'type' => 'integer' ), ) ); } );
register_meta( $object_type, $meta_key, $args )
register_meta() registers a meta-field. If the show_in_rest = true parameter is specified when registering the meta-field, this field will be available in the REST API and will be shown in the response under the meta key. This meta-field can also be created/updated through REST requests.
- $object_type(string) (required)
- The object type for which the meta-field is registered:
post
,user
,comment
,term
. The $meta_type parameter from the functions {add/get/update/delete}_metadata( $meta_type, ...) - $meta_key(string) (required)
- The name of the key being registered.
- $args(array) (required)
Data describing the meta-field. By default, these are:
$args = array( 'object_subtype' => '', 'type' => 'string', 'description' => '', 'single' => false, 'sanitize_callback' => null, 'auth_callback' => null, 'show_in_rest' => false, );
register_meta() is a general function; there are wrappers to conveniently register meta-fields for posts and taxonomy items:
Example
This example shows how to create a field that can be read, created, and updated in the REST API.
Updating the field will be available via the request: POST wp-json/wp/v2/posts/{id}, and creating it via the request POST wp-json/wp/v2/posts/.
Note: if the custom-fields property is not specified in the supports
parameter when registering a post type, meta-fields will not be displayed in the REST API.
// Registering a meta-field for the 'post' post type with REST API support register_post_meta( 'post', 'my_meta_key', array( // field type, can be: 'string', 'boolean', 'integer', 'number'. // the specified type is used for sanitizing the field when writing and outputting. 'type' => 'string', // description will be shown in the schema key. 'description' => 'A meta key associated with a string meta value.', // the meta-field can have only one value. 'single' => true, // use the field in the WP REST API 'show_in_rest' => true, ) );
Adding _links to the API Response
WordPress generates a list of links related to the requested resource to simplify navigation to related resources. More details here.
{ "_links": { "self": [ { "href": "https://make.wordpress.org/core/wp-json/wp/v2/posts/28312" } ], "collection": [ { "href": "https://make.wordpress.org/core/wp-json/wp/v2/posts" } ], "author": [ { "embeddable": true, "href": "https://make.wordpress.org/core/wp-json/wp/v2/users/8670591" } ], "replies": [ { "embeddable": true, "href": "https://make.wordpress.org/core/wp-json/wp/v2/comments?post=28312" } ], "wp:term": [ { "taxonomy": "category", "embeddable": true, "href": "https://make.wordpress.org/core/wp-json/wp/v2/categories?post=28312" }, { "taxonomy": "post_tag", "embeddable": true, "href": "https://make.wordpress.org/core/wp-json/wp/v2/tags?post=28312" } ] } }
The _links key in the JSON object is not contained in WP_REST_Response::$data and is not accessible via WP_REST_Response::get_data(), because this key is added just before the response is returned.
A custom link can be added via the method:
WP_REST_Response::add_link( $rel, $href, $attributes )
- $rel(string)
- The relationship of the link. It should be a string from the available IANA list. Or you can specify a URL registered as a "Compact URL (CURIE)". Example CURIE: https://api.w.org/term will turn into wp:term when generating the API response.
- $href(string)
- URL of the link.
- $attributes(array)
A list of link attributes. Various parameters can be included here (depending on the resource controller).
embeddable
- includes support for embedding (_embedded), when the _embed parameter is enabled. If multiple links are added with the same relationship, the embeddings will be in the same order in which the links were added.
Examples of adding a link:
$response->add_link( 'author', rest_url( "/wp/v2/users/{$post->post_author}" ) ); $response->add_link( 'https://api.w.org/term', add_query_arg( 'post', $post->ID, rest_url( "/wp/v2/{$tax_base}" ) ) ); $response->add_link( 'author', rest_url( "/wp/v2/users/{$post->post_author}" ), array( 'embeddable' => true, ) ); $response->add_link( 'author', rest_url( "/wp/v2/users/{$additional_author}" ), array( 'embeddable' => true, ) );
Example of implementing links to posts with multiple authors. The order of adding links is preserved.
{ "_links": { "author": [ { "embeddable": true, "href": "https://yourwebsite.com/wp-json/wp/v2/users/1" }, { "embeddable": true, "href": "https://yourwebsite.com/wp-json/wp/v2/users/2" } ] }, "_embedded": { "author": [ { "id": 1, "name": "Primary Author" }, { "id": 2, "name": "Secondary Author" } ] } }
Registering Your Compact URL (CURIE)
CURIEs - "Compact URIs" - URLs are written in a compact form to look clear and universal in the API response. The concept was introduced in WP version 4.5.
Example CURIE: https://api.w.org/term will turn into wp:term when generating the API response.
All variants:
https://api.w.org/items = wp:items https://api.w.org/featuredmedia = wp:featuredmedia https://api.w.org/attachment = wp:attachment https://api.w.org/term = wp:term https://api.w.org/post_type = wp:post_type
You can add your CURIEs via the filter rest_response_link_curies.
For example, let's transform the link https://api.mypluginurl.com/my_link into my_plugin:my_link in the API response.
add_filter( 'rest_response_link_curies', 'my_plugin_prefix_register_curie' ); function my_plugin_prefix_register_curie( $curies ) { $curies[] = array( 'name' => 'my_plugin', 'href' => 'https://api.mypluginurl.com/{rel}', 'templated' => true, ); return $curies; }