As stated in the Object Meta Type section of the Modifying Responses page in the REST API Handbook:
When registering
object
meta, setting thetype
toobject
is not sufficient, you also need to inform WordPress of what properties to allow. This is done by writing a JSON Schema when registering the metadata.
Interestingly, register_meta()
will throw an error if you register an array
type without a schema, but it doesn’t seem to perform this check for the object
type. I’m not clear on why.
The schema format is an adaptation of the JSON Schema Version 4 specification, with a couple deviations.
In this case, a schema to describe an object such as { firstName: 'John', lastName: 'Doe' }
might look as such:
register_post_meta( $post_type, '_example_meta_key', [
'auth_callback' => function() {
return current_user_can('edit_posts');
},
'show_in_rest' => [
'schema' => [
'type' => 'object',
'properties' => [
'firstName' => [
'type' => 'string',
],
'lastName' => [
'type' => 'string',
],
],
],
],
'single' => true,
'type' => 'object',
]);
Also note that when registering meta for a post type for use in REST API interactions, it is required that the post type has custom-fields
support. While you can use an empty string to address all available post types, when interacting with meta for a post over the REST API (such as through Gutenberg APIs), the operation will fail if the post’s post type does not support custom-fields
.
Addendum: Dynamic Properties Schema
If you’re unsure of what the keys of your properties will be or how many there might be, you can use the additionalProperties
keyword in the object schema to specify a schema for all other properties which are not otherwise addressed.
The object
type supports a number of additional keywords and constraints to further define an object’s schema as well.
In the case described in the comments, a schema to describe the object
{
default_profile: { isRestricted: true },
profile_one: { isRestricted: true },
profile_two: { isRestricted: true },
}
with unknown “profile names” / an unknown number of profile entries could be written as such:
'show_in_rest' => [
'schema' => [
'type' => 'object',
'additionalProperties' => [
'type' => 'object',
'properties' => [
'isRestricted' => [
'type' => 'boolean',
],
],
],
],
],