Skip to content

REST API: Add a shared helper for JSON Schema allowed keywords#12234

Open
gziolo wants to merge 2 commits into
WordPress:trunkfrom
gziolo:add/64955-json-schema-allowed-keywords
Open

REST API: Add a shared helper for JSON Schema allowed keywords#12234
gziolo wants to merge 2 commits into
WordPress:trunkfrom
gziolo:add/64955-json-schema-allowed-keywords

Conversation

@gziolo

@gziolo gziolo commented Jun 19, 2026

Copy link
Copy Markdown
Member

What

Add a shared helper, wp_get_json_schema_allowed_keywords(), so Core has one place to decide which JSON Schema keywords may stay in schema output.

It supports two profiles:

  • rest-api — the existing REST API keyword set. This is the default and is used for REST route output.
  • draft-04 — a larger JSON Schema draft-04 set, used when publishing schemas to clients such as the Abilities API. It keeps documentation and passthrough keywords like $ref, definitions, allOf, not, dependencies, and additionalItems.

Why

This centralizes schema keyword allow-listing in a general-purpose place and removes the Abilities-specific special casing from the REST controller. It is a preparatory step for the AI schema compiler work.

The change keeps a clear line between two ideas:

  • Preserved in schema output — keywords allowed to stay when a schema is serialized to JSON.
  • Validated by WordPress — keywords the server actually enforces.

REST route schema output now flows through the helper, so it can be adjusted with the new wp_json_schema_allowed_keywords filter. Validation internals still call rest_get_allowed_schema_keywords() directly, so REST validation behavior does not change.

Testing

New unit tests cover the default profile and the unknown-value fallback, the draft-04 keyword set, and that the filter receives the schema profile. A REST server test confirms the filter reaches route schema output. The existing Abilities schema test now sources its allowed keywords from the shared helper.

npm run test:php -- --filter='test_wp_get_json_schema_allowed_keywords|test_get_data_for_route_includes_filtered_json_schema_keywords|test_core_abilities_schemas_use_only_valid_keywords'

Trac ticket: https://core.trac.wordpress.org/ticket/64955

🤖 Generated with Claude Code

Introduce wp_get_json_schema_allowed_keywords() as one place to decide
which JSON Schema keywords may stay in schema output. It supports two
profiles: 'rest-api' for REST route output (the existing keyword set)
and 'draft-04' for the larger set used when publishing schemas to
clients, such as the Abilities API.

REST route schema output now flows through the new helper, so it can be
adjusted with the new 'wp_json_schema_allowed_keywords' filter.
Validation internals keep calling rest_get_allowed_schema_keywords()
directly, so validation behavior does not change.

The Abilities list controller now reads its passthrough keywords from
the 'draft-04' profile instead of a private constant.

This is a preparatory step for the AI schema compiler work.

See #64955.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Hi there! 👋

Thank you for your contribution to WordPress! 💖

It looks like this is your first pull request to wordpress-develop. Here are a few things to be aware of that may help you out!

No one monitors this repository for new pull requests. Pull requests must be attached to a Trac ticket to be considered for inclusion in WordPress Core. To attach a pull request to a Trac ticket, please include the ticket's full URL in your pull request description.

Pull requests are never merged on GitHub. The WordPress codebase continues to be managed through the SVN repository that this GitHub repository mirrors. Please feel free to open pull requests to work on any contribution you are making.

More information about how GitHub pull requests can be used to contribute to WordPress can be found in the Core Handbook.

Please include automated tests. Including tests in your pull request is one way to help your patch be considered faster. To learn about WordPress' test suites, visit the Automated Testing page in the handbook.

If you have not had a chance, please review the Contribute with Code page in the WordPress Core Handbook.

The Developer Hub also documents the various coding standards that are followed:

Thank you,
The WordPress Project

@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props gziolo.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@gziolo gziolo self-assigned this Jun 19, 2026
@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Rename the Abilities controller cache to $allowed_schema_keyword_lookup
to show it holds a keyword-keyed map for array_intersect_key(), not a
plain list. Drop the manual remove_filter() calls in the new tests since
WP_UnitTestCase restores hooks automatically. Document why the draft-04
keyword test checks 'type' separately.

See #64955.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gziolo gziolo requested a review from jorgefilipecosta June 19, 2026 14:10
* @since 7.1.0
* @var array<string, true>|null
*/
private $allowed_schema_keyword_lookup = null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you remove null as valid value, you should be able to use type hint, and the condition below can just check for isset() if I’m not mistaken. That should improve quality a bit

* @return array<string, true> Allowed schema keywords.
*/
private function get_allowed_schema_keywords_for_response(): array {
if ( null === $this->allowed_schema_keyword_lookup ) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See note above

*/
private function get_allowed_schema_keywords_for_response(): array {
if ( null === $this->allowed_schema_keyword_lookup ) {
$this->allowed_schema_keyword_lookup = array_fill_keys( wp_get_json_schema_allowed_keywords( 'draft-04' ), true );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not fully familiar with this area of WP, but draft-04 looks strange, are you sure this is correct?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REST API uses a subset of draft-04 with elements from draft-03 JSON Schema specification. Abilities API allows using the semantic format for input and output schema as a REST API, but it transforms it to draft-04 when sending through the REST API to ensure that on the client, it gets the same validation against stricter draft-04.

The intent is correct, and the naming can have adjustments based on the feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants