WordPress REST API provides an interface for fetching, adding, updating, and deleting data from a WordPress site in a uniform way.
While the schema for the data types that are available in the REST API is quite extensive,
there may be times when you need to store additional data that is not part of the core schema.
In this lesson, you will learn about two methods of adding fields to your REST API requests,
either by enabling custom fields in the REST API route, or by making custom fields available as top-level fields.
You'll also learn about the pros and cons to both approaches.
If you skipped the previous lessons in this module, download version 1.0.2 of the bookstore plugin
from the link in the repository README, and install and activate the plugin on your local WordPress install.
Additionally, if you haven't done it already, download and install the Postman app for your operating system.
Before you get started, it's important to note that modifying WordPress REST API responses can have unexpected consequences.
Changing or removing data from core REST API endpoint responses can break plugins or WordPress core behavior,
and should be avoided wherever possible.
If you need to retrieve a subset of data from a REST API request, the recommended method is to rather use the fields global parameter
to limit the fields returned in the response.
For example, you can use the fields parameter to limit the fields to just id and title,
if those are the only fields you need for your application.
Adding fields to a REST API response is less risky, and so this lesson only covers adding fields.
If you watch the lessons in the introduction to WordPress plugins module, you will have learned about custom fields, also known as metadata.
These fields are often used on custom post-ups to store additional pieces of data that are specific to that post-up.
Under the hood, these custom fields are stored in the post-meta table, as a set of key value pairs attached to the post by the post ID.
Beyond posts, WordPress also supports metadata on other data types, such as comments and users.
You can read more about this in the metadata API documentation.
WordPress REST API allows you to create or update custom fields when creating or updating data.
This is possible by passing an object of key value pairs to the meta property of the post type you're working with.
However, in order to use a custom field, you have to register it first.
This is done using the register-meta function.
If you wanted to register a custom field called location on a post, you could use the register-meta function like this.
While it's possible to add this anywhere to a plugin, it's recommended to add it to something like the Annette action hook.
It's important to ensure that the showInRest property is set to true, otherwise the custom field will not be available in the REST API.
This would enable the custom field to be added to the REST API schema for a post,
and will also allow you to post data to that custom field using the REST API.
This is handled by passing a custom field as a key value pair in the meta object of the request file.
You can test this by creating a new post request in postmap and sending that request to the post root.
Let's take postbook, duplicate it, and change it to the post post.
Post it to the post endpoint.
The authorization is already set to basic auth.
And then for the body, we can pass in my_post and my_post.
Then this is published, and then we'll set up the meta object,
which is another JSON object,
passing the location meta key and the location value.
Save and send.
Post has been created, and London is set as the meta location.
Right now it's a WordPress 4.9.8 custom field set to show in REST using register_meta, where registered for all objects of a given type.
For example, if you added a custom field to the posts type,
and then created a custom post type, like book, the custom field will automatically be available on the custom post.
As of WordPress 4.9.8, it's now possible to use register_meta with an object subtype argument
that allows one to reduce the usage of the meta key to a particular post type.
For example, let's say you wanted to register an ISBN custom field only to the book custom post type.
To start, you'll need to update the custom post type to support custom fields.
Call register_meta, pass in post, and set up the custom field as ISBN.
Then we'll specify the array of arguments.
Scroll that up a little bit, and we'll say, "
"Make sure it's available in the REST API."
That's true.
And then finally, specify the object subtype as a buffer.
You would now have an ISBN custom field available only on the book post type.
You can test this by adding a book via the REST API.
In Postman, create or update the post request to the box root,
and include the meta object with the ISBN field.
Let's say Postman book 2, and meta object by ISBN, and we'll just pass in a random string.
If you then edit the book in the WordPress admin, you'll see that the ISBN field is in the custom fields panel, if you have it enabled.
It's also the only custom field available for the book post type.
The other way to add custom fields to the WordPress REST API is to add them as top-level fields in the API responses.
In the earlier example, the ISBN was registered as a meta field,
and therefore only available in the meta object of the REST API response.
But what if you prefer to have it as a top-level field alongside the title, content, and exit?
This can be achieved using the register REST field function.
Let's take a look at how this could be implemented.
First, you need to register your REST fields on the REST API and net action hook.
This is to ensure that the field is only registered on the REST API.
We'll add action on the REST API net hook, and we set up a callback function.
Then we can create that function,
ready to register the REST field.
Then you should use the register REST field function to register the field.
The first parameter is the object type the field should be registered on.
This can be a string for a single object, or an array for more than one object.
In this case, just register the field on the book custom post type.
The second argument is the name of the field.
In this case, just make it the same as the custom field, ISBN.
The third parameter is an array of arguments that determines how the field functions.
You need to pass at least the following three arguments to the array.
GetCallback is a function that returns the value of the field.
UpdateCallback is a function that updates the value of the field,
and schema, which is an array containing the schema for the field.
For now, you can leave the schema argument of the REST field as null,
but you will need to specify the GetCallback and UpdateCallback functions.
These are the functions that will be triggered when the API request is made,
either to fetch the data, or create or update the data.
So for GetCallback, we could say something like "get ISBN".
And for UpdateCallback, we can set up something like "update ISBN".
Now we need to create those functions, so function "get ISBN" and "update ISBN".
By default, an array of the post types prepared data is passed to the GetCallback function as the first argument.
An implementation of this function could be as straightforward as returning the value of the custom field.
So if we set up the argument, and then return "get post meta",
give it the BookID, and specify the ISBN field,
and pass it back as a single value.
The value sent for the field from the REST API create update request is passed to the UpdateCallback function as the first argument,
and a model object, in other words the book, as the second.
Let's pop those in there.
An implementation of this function could be as simple as updating the value of the custom field.
So you could use something like return, update post meta,
get the BookID from the object,
specify the meta field,
and send it the new value.
If you test this out by creating a new book,
and passing a value for the ISBN field, you'll see the data being saved to the post meta tab,
but it is also displayed as a top level field in the REST API response.
So there we have the ISBN field as a top level field,
and if we save and send that request,
it creates the record, but it has the ISBN field as a top level field.
The schema argument is an array that describes the schema for the field.
While it's not a requirement, including a schema is encouraged.
If nothing else, it helps future developers understand what the field is for.
It can also be used to validate the data being sent when creating automated API requests.
So an example of a schema implementation could be as simple as specifying a description and a type.
You can read more about how to define the schema for REST API resources and fields
in the section on schema in the REST API Handbook.
When deciding whether to only use register meta or to use register REST field,
you should consider the pros and cons of each approach.
The main advantage of using the register meta only route is that you do not need to add any further code
to enable storing or retrieving data from the custom fields,
as long as you remember to fetch and save the data using the meta object in your application code.
You enable the field to show in the REST API, and you can use it straight away.
This is also the more performant option, as it does not add any additional code that needs to be executed.
On the other hand, the advantage of using the register REST field route
is that you can perform additional processing on the data before it is returned or before it is sent.
For example, you could perform some validation on the data before it's saved to the database.
You could also add hooks to the get callback and update callback functions
to either perform additional processing on the data or allow other developers to extend your custom fields.
The downside is that you're adding a slight overhead to the API requests,
as it adds more code that needs to be executed.
Ultimately, the route you decide should be decided on a case-by-case basis.
For more information on modifying REST API responses,
check out the Modifying Responses section of the WordPress REST API Handbook.