Modify WordPress REST routes with register rest field
Tags: wordpress, javascript, php, tutorial
Published: 2021-09-29 14:40:40

---
title: Modify WordPress REST routes with register rest field
published: true
date: 2021-09-28 20:26:42 UTC
tags: wordpress,javascript,php,tutorial
canonical_url: https://indexforwp.com/modify-wordpress-rest-routes-with-register-rest-field/
---

## Getting Started

The `register_rest_field` function is a PHP function that allows you to add extra fields to any registered endpoint (posts, pages, custom post types, terms, users, etc). The function takes three parameters:

```php
register_rest_field(
	$object_type,
	$attribute,
	$args
);
```

The `$object_type` parameter is any data type in WordPress, and can be an array of multiple types, or a string for a single type. Next, the `$attribute` parameter is the name of the field you want to register and will show up in the rest response as the key name.

Finally, the `$args` parameter is an array with a getter, setter, and schema definition. All three arguments are optional, so you have a lot of flexibility in how you control your field.

## Registering a field

Let’s build a real example. In this case we’re going to register a field for posts that shows how many “slaps” the post has, along with a setter to add slaps whenever the user clicks a “slap this post” button.

First we want to target posts and name our attribute:

```php
add_action('rest_api_init', function() {
	register_rest_field(
		'post',
		'slap_count',
		// ... getters and settings
	);
});
```

Note: wrap your `register_rest_field` calls in the `rest_api_init` action to ensures the rest api is loaded

### Getting the value

While the above is the only required code to use the `register_rest_field` function, the field won’t show up in your REST endpoint without at least a get value. Let’s take care of that now:

```php
add_action('rest_api_init', function() {
	register_rest_field(
		'post',
		'slap_count',
		// NEW CODE
		array(
			'get_callback' => function($object) {
				$slap_count = get_post_meta( $object['id'], 'slap_count', true );

				return $slap_count ? $slap_count : 0;
			}
		)
	);
});
```

The `get_callback` argument accepts an `$object` parameter, which in this case is an individual post (passed as an array). Inside of the callback we can use standard WordPress functions like `get_post_meta`. In this case, we are grabbing the slap\_count meta field and returning either the value or 0.

If you query an single post using the `/wp-json/wp/v2/posts/<id>` endpoint, you should see this line in the response:

```json
"slap_count": 0 // or whatever the value is
```

For our example, the field so far is pretty useless but if you just wanted to output a value directly then the above is all you need.

### Setting the value

To allow updates to the value, add a `update_callback` argument to the `$args` array:

```php
add_action('rest_api_init', function() {
	register_rest_field(
		'post',
		'slap_count',
		array(
			'get_callback' => function($object) {
				$slap_count = get_post_meta( $object['id'], 'slap_count', true );

        			return $slap_count ? $slap_count : 0;
			},
			// NEW CODE
			'update_callback' => function ( $value, $object ) {
          			$slap_count = get_post_meta( $object->ID, 'slap_count', true );

          			update_post_meta( $object->ID, 'slap_count', $slap_count + 1 );
			},
		)
	);
});
```

The `update_callback` function takes two parameters: `$value` and `$object`. In our case we aren’t using the value variable, but instead just adding 1 to the value whenever the callback is fired.

_Note: in this function `$object` is passed as an object type instead of an array like `get_callback`._

### Triggering an update

To actually fire the `update_callback` function, simply call the `/wp-json/wp/v2/posts/<id>` endpoint with the POST method, and pass the field name through the body as JSON:

```javascript
// Javascript example
fetch('/wp-json/wp/v2/posts/1', {
	// make sure to authenticate or pass the X-WP-Nonce value as a header
	method: 'POST',
	body: JSON.stringify({
		"slap_count": 1 // reminder that the value doesn't matter for our example as we just increment the count by one
  	})
})
.then(response => response.json())
.then(data => {
  	// ... the updated post object is returned here
})
.catch(error => console.log('error', error));
```

## Securing your field

As always, a little security goes a long way. The third parameter in the `register_rest_field` $args array is a schema array with sanitization and validation options:

```php
add_action('rest_api_init', function() {
	register_rest_field(
		'post',
		'slap_count',
		array(
			// ...get_callback
			// ...update_callback

			// NEW CODE
			'schema' => array(
				'type' => 'string' // the type of value we expect to be passed back
				'sanitize_callback' => function($value) {
					// run sanitization here
       				},
        			'validate_callback' => function ($value) {
            				// run sanitization here
        			},
			)
		)
	);
});
```

The `schema` parameter takes three arguments:

- the type of the value (int, string, boolean, etc)
- A sanitization callback to sanitize the input
- A validate callback to make sure it conforms to some set of rules

If you haven’t already, read more on sanitizing and validating values accepted into your rest routes [here](https://indexforwp.com/how-to-secure-your-own-rest-api-routes-in-wordpress/). The same options can be used in the schema callback functions.

## Wrap Up

In just a few lines of code, you can completely customize WordPress’ built-in REST routes with your own data. Or combine and extend existing values to avoid unnecessary work in Javascript and prevent multiple REST calls to grab necessary data.

**Author**

{% user david_woolf %}