When we look at the standard REST API responses it’s clear to see that many download data operations will need additional queries to be effective. One possible solution for this issue is the addition of custom fields to the responses the REST API returns.
What’s the best way to add custom fields in the WordPress?
There’s two possible methods for adding custom fields to to REST API responses:
- By modifying the data via the rest_prepare_post filter.
- By adding a new field using the register_api_field function and the rest_api_init action.
The first method is technically easier to implement, so I would recommend it when we have to modify REST API responses. However, before we can use the first method we need to add support for the rest_insert_post action so that we can add posts that include the our new field.
Additionally, there are some important principles to bear in mind when working with this method:
- Modifying the standard content fields of REST API responses risks making your chosen solution incompatible with other elements that use the same installation of the REST API. For this reason we should apply this method only in dedicated solutions that have a known list of extensions that will rely on the REST API so conflicts are avoided.
- If we add a new field, then we should give it a unique prefix so we’re safe from conflicts caused by someone else adding a field with the same name but different content.
- When we need to add several additional fields, it’s important to consider our own plugin or theme endpoints; in cases where many plugins are adding their own fields to the REST API responses the size of individual positions in the response will increase significantly. Besides, having our own end-points allows us to better optimize the response content.
Adding a new field with the rest_prepare_post filter
if(!function_exists('slug_add_data')) : function slug_add_data($response, $post) { $response->data['slug_category'] = ''; $categories = get_the_category($post->ID); if(count($categories)) { $category_slug = $categories[0]->slug; $response->data['slug_category'] = $category_slug; } } } add_filter('rest_prepare_post', 'slug_add_data', 10, 3);
In the above example we add a slug_category field to the /wp/v2/posts endpoint in the REST API response, which will include the simplified name of the first category to which the post was added.
Adding a new field with the register_api_field function
The described below requires more code, but it’s more elegant and opens up many more possibilities for expanding our functionality.
The code adding meta data to results containing posts will look something like this:
function slug_add_post_data() { register_api_field('post', 'slug_field', array( 'get_callback' => 'slug_get_field', 'update_callback' => 'slug_update_field', 'schema' => array( 'description' => 'My special field', 'type' => 'string', 'context' => array('view', 'edit') ) ) ); } add_action('rest_api_init', 'slug_add_post_data'); function slug_get_field($post, $field_name, $request) { return get_post_meta($post->id, $field_name); } function slug_update_field($value, $post, $field_name) { if (!$value || !is_string($value)) { return; } return update_post_meta($post->ID, $field_name, strip_tags($value)); }
The process of adding a field is achieved via the rest_api_init action by calling the register_api_field function. This function takes three arguments:
- The type of resource to add to a new field.
- The name of the new field (remember to add a unique prefix!)
- An array of additional arguments.
The most important is the last argument, as here we specify:
- The function responsible for returning the correct data.
- The function that performs any operations when creating a new resource.
- The structure of the new field being added.
The function responsible for returning the data has access to the post object, the field name, and query object. It will be used when using GET queries.
On the other hand, the update function has access to a new value, post object and the field name. It will be used with POST and PUT/PATCH operations.
The last element of the array is a schema element; specifying its value is not required, but if we want our field to be described in the structure of its endpoint, then it’s worth adding a short associative array that includes information about this field (as seen in the above code).
Summary
The standard REST API may not offer an optimal solution to get all the data we need, but using its features, filters and actions we may easily add missing fields. In my next article discussing the REST API, we’ll look at creating our own custom endpo