REST API Team Update (4.7 week 7)

Our two (pt1) part (pt2) (split due to team travel) weekly meeting is now complete, and we have some new updates from the APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. team!

Team review & commentary is requested on “Open Questions on Settings” and “Open Questions on MetaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress.”, below.

Settings

This Pull Request for adding Settings support to the API, resolving one of the few remaining major content gaps in the API, is almost ready to be merged into the rest-api feature pluginFeature Plugin A plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See Features as Plugins.. Settings are exposed as keys on the resource `/wp/v2/settings`, e.g.:

{
    title: 'WordPress Develop',
    description: 'Just another WordPress site',
    url: 'http://src.wordpress-develop.dev',
    email: 'admin@local.dev',
    timezone: '',
    date_format: 'F j, Y',
    time_format: 'g:i a',
    start_of_week: 1,
    language: 'en_US',
    use_smilies: true,
    default_category: 1,
    default_post_format: '0',
    posts_per_page: 10
}

This resource is only accessible or modifiable if you are authenticated as a user with the `manage_options` capability.

Open Questions on Settings

Team feedback is requested on the below, and on the settings proposal in general.

  1. What do we do if a setting value in the database does not match the type used in `register_setting`?
    • This becomes a problem when there is serialized data in the `option` value. Right now we are forcing this to be a `null` value in the rest apiREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. responses. The problem with this approach is that sending that response data back to the settings endpoint will cause the deletion of that option value (as `null` in this case is essentially a delete operation).
  2. Having support for `object` recursion and `array` types in the Schema would be very nice, allowing settings that are either objects or arrays.
    • We propose that does not need to be resolved prior to merge, and may be added in a subsequent cycle.
  3. Currently, reading all options at `/wp/v2/settings` is behind a `manage_options` cap check: we need to work out if we want to publicly expose option values for some settings.
    • If we do this, we’d need a way in `register_setting` (or via some kind of `read_setting` meta cap) to work out which settings should be exposed publicly (or at specific permissions checks).
    • Site title and description are still available on the root `/wp-jsonJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML./` resource index; several other settings here can be inferred from other responses or site content. We propose that this resource be left as requiring `manage_options` caps, and move establishing a mechanism in coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. to register a setting as public be handled in a subsequent development cycle.

Setting Registration

For your settings to be exposed in the REST API, you need to register them. WordPress includes a register_setting function which is not usually required to get/set options, but is required for API support.

To register your field, simply call register_setting and set the show_in_rest flag to true.

register_setting( 'group', 'option_name', array(
    'show_in_rest' => true,
));

register_setting Arguments

register_setting is part of WordPress core, but isn’t heavily used in most parts of core, so you may not have seen it before. Here are the options relevant to the REST API:

  • show_in_rest – Should the setting be exposed in the API? true for default behaviour, or an array of options to override defaults (see below).
  • type – This is the type of data the setting is. Can be `string`, `number`, or `boolean` (so far).
  • description – Human-readable description of what the field is for. The API exposes this in the schema.
  • sanitize_callback – Callback to sanitize the value before it’s stored in the database. See the "sanitize_{$object_type}_meta_{$meta_key}" filter.

REST API-Specific Arguments

The show_in_rest parameter defaults to false, but can be set to true to enable API support. Out of the box, the API makes some assumptions about your setting, but you can override these by setting show_in_rest to an options array instead:

register_setting( 'group', 'option_name', array(
    'show_in_rest' => array(
        'name' => 'fieldname'
    )
));

The options you can set are:

  • name – The key exposed via the REST API. For example, if your setting starts with an underscore, you may want to remove this for the API.
  • default – The default value for the setting via the REST API if it’s not set in the database.
  • schema – The JSON Schema options for the field. Exposed via OPTIONS requests to the post. This is generated automatically based on other parameters, but can be specified manually if you’d like to override it.

Settings Defaults

We’d also love feedback on ticketticket Created for both bug reports and feature development on the bug tracker. #38176, this adds the ability to specify a default value for an option via `register_setting()`. As you can see from the above, we are currently defining the `default` value within
the `show_in_rest` options, as there’s no way to do this in the Settings API. We’d like for there to be a way to do this in core, so `get_option()` could default to the value set in `register_setting( … [ default => ‘myvalue’ ])`
when no default is specific in `get_option`.

Meta

Meta is also ready to be merged into the plugin, and also could use review from the broader WordPress team. Similar to custom post types and taxonomies, and as discussed previously, only meta that opts-in to API support is available through the REST API.

Open Questions on Meta

  1. Right now, all meta registered through the mechanism below is assumed to be visible wherever its parent object appears. Meta values registered to a public post will be visible on that post without authentication.
    • Is it acceptable to expose registered meta fields on objects in this way, where the meta visibility will match the visibility of the parent object?
  2. As described in this comment, when you have multiple of the same value stored in a meta key, it will delete all matching values. For example, if you had a meta value [ 11, 13, 13, 13, 13 ] and attempted to remove one 13, it would result in the value [ 11 ].
  • Should multiple instances of the same value be able to be stored in a `single => false` meta field?

Meta Registration

For your meta fields to be exposed in the REST API, you need to register them. WordPress includes a register_meta function which is not usually required to get/set fields, but is required for API support.

To register your field, simply call register_meta and set the show_in_rest flag to true.

register_meta( 'post', 'field_name', array(
    'show_in_rest' => true,
));

Note: register_meta must be called separately for each meta key.

register_meta Arguments

register_meta is part of WordPress core, but isn’t heavily used in most parts of core, so you may not have seen it before. Here are the options relevant to the REST API:

  • show_in_rest – Should the field be exposed in the API? true for default behaviour, or an array of options to override defaults (see below).
  • description – Human-readable description of what the field is for. The API exposes this in the schema.
  • single – Is this field singular? WordPress allows multiple values per key on a single object, but the API needs to know whether you use this functionality.
  • sanitize_callback – Callback to sanitize the value before it’s stored in the database. See the "sanitize_{$object_type}_meta_{$meta_key}" filter.
  • auth_callback – Callback to determine whether the user can write to the field. See the "auth_post_{$post_type}_meta_{$meta_key}" filter.

REST API-Specific Arguments

The show_in_rest parameter defaults to false, but can be set to true to enable API support. Out of the box, the API makes some assumptions about your meta field, but you can override these by setting show_in_rest to an options array instead:

register_meta( 'post', 'field_name', array(
    'show_in_rest' => array(
        'name' => 'fieldname'
    )
));

The options you can set are:

  • name – The key exposed via the REST API. For example, if your meta key starts with an underscore, you may want to remove this for the API.
  • schema – The JSON Schema options for the field. Exposed via OPTIONS requests to the post. This is generated automatically based on other parameters, but can be specified manually if you’d like to override it.

Using Meta over the API

Meta is added to existing resources as a new meta field. For example, to get the meta for a single post, fetch the post at /wp/v2/posts/{id}, then look in the meta field. This is a key-value map for the registered fields.

To update a field, simply send back a new value for it.

Setting a field to null will cause the value to be removed from the database. If a field has a default value set, this essentially “resets” the value to the default (although no default will be stored in the database).

For meta fields which can hold multiple values, this field will be a JSON list. Adding or removing items from the list will create or remove the corresponding values in the database.

Other Updates

#4-7, #rest-api