pinkcrab / wp-rest-schema
Library for writing WP Json Rest Schema
Requires
- php: >=8.0.0
Requires (Dev)
- dealerdirect/phpcodesniffer-composer-installer: *
- gin0115/wpunit-helpers: 1.1.*
- php-stubs/wordpress-stubs: 6.6.*
- phpstan/phpstan: *
- phpunit/phpunit: ^8.5 || ^9.0
- roots/wordpress: 6.6.*
- squizlabs/php_codesniffer: 3.*
- symfony/var-dumper: <=6.2.7
- szepeviktor/phpstan-wordpress: *
- vlucas/phpdotenv: <=5.5.0
- wp-coding-standards/wpcs: ^3
- wp-phpunit/wp-phpunit: 6.6.*
- yoast/phpunit-polyfills: ^1.0.0 || ^2.0.0
- dev-master
- 1.0.0-RC1
- 0.0.1-beta3
- 0.0.1-beta2
- 0.0.1-beta
- dev-dependabot/composer/yoast/phpunit-polyfills-tw-1.0.0or-tw-2.0.0or-tw-4.0.0
- dev-dependabot/composer/php-stubs/wordpress-stubs-6.6.staror-6.9.star
- dev-dependabot/composer/wp-phpunit/wp-phpunit-6.6.staror-6.9.star
- dev-dependabot/composer/roots/wordpress-6.6.staror-6.9.star
- dev-dependabot/composer/vlucas/phpdotenv-lte-5.7.0
- dev-release/1.0.0-RC1
- dev-develop
- dev-feature/finish-initial-release
- dev-dependabot/composer/yoast/phpunit-polyfills-tw-0.2.0or-tw-1.0.0or-tw-3.0.0
- dev-dependabot/composer/roots/wordpress-tw-5.6or-tw-6.0
- dev-dependabot/composer/wp-phpunit/wp-phpunit-tw-5.0or-tw-6.0
- dev-dependabot/composer/php-stubs/wordpress-stubs-tw-5.6.0or-tw-6.0.0
- dev-feature/use-new-pipeline
- dev-feature/update-dev-deps-perique-2_0_1
- dev-feature/gh17-update-dev-deps-to-wp6_1
- dev-feature/gh12-update-dev-deps
- dev-feature/create-parsers
- dev-feature/import-from-perique-route
This package is auto-updated.
Last update: 2026-03-06 16:56:00 UTC
README
A fluent PHP builder for WordPress REST API JSON schemas. Converts verbose nested array definitions into clean, chainable method calls.
Why?
Defining valid JSON rest schema in WordPress means writing deeply nested associative arrays. It's easy to make mistakes, hard to read, and painful to maintain. This library provides a fully fluent, type-safe builder API that mirrors every keyword from WordPress's rest_get_allowed_schema_keywords().
Instead of this:
register_post_meta( 'post', 'fixed_in', array( 'type' => 'string', 'single' => true, 'show_in_rest' => array( 'schema' => array( 'type' => 'string', 'minLength' => 10, 'maxLength' => 42, 'required' => true, 'description' => 'Required string, 10-42 chars.', ), ), ) );
Write this:
register_post_meta( 'post', 'fixed_in', array( 'type' => 'string', 'single' => true, 'show_in_rest' => array( 'schema' => Argument_Parser::for_meta_data( String_Type::field( 'fixed_in' ) ->min_length( 10 ) ->max_length( 42 ) ->required() ->description( 'Required string, 10-42 chars.' ) ), ), ) );
Setup
$ composer require pinkcrab/wp-rest-schema
Requirements: PHP >= 8.0 | WordPress >= 6.6
Available Types
| Type | Class | Type-Specific Methods |
|---|---|---|
| String | String_Type |
min_length(), max_length(), pattern() |
| Integer | Integer_Type |
minimum(), maximum(), exclusive_minimum(), exclusive_maximum(), multiple_of() |
| Number | Number_Type |
minimum(), maximum(), exclusive_minimum(), exclusive_maximum(), multiple_of() |
| Boolean | Boolean_Type |
No type-specific methods |
| Null | Null_Type |
No type-specific methods |
| Array | Array_Type |
string_item(), integer_item(), min_items(), max_items(), unique_items(), any_of(), one_of() |
| Object | Object_Type |
string_property(), integer_property(), additional_properties(), pattern_properties(), min_properties(), max_properties() |
Boolean_TypeandNull_Typeinherit all shared methods from the baseArgumentclass but have no additional type-specific methods. See Argument for the full shared API.
All types share a common set of methods for description, default, required, readonly, title, format, expected (enum), context, validation, sanitization, and union types. See Argument (Base Class) for details.
Quick Examples
Post Meta Schema
use PinkCrab\WP_Rest_Schema\Argument\String_Type; use PinkCrab\WP_Rest_Schema\Parser\Argument_Parser; register_post_meta( 'post', 'color', array( 'type' => 'string', 'single' => true, 'show_in_rest' => array( 'schema' => Argument_Parser::for_meta_data( String_Type::field( 'color' ) ->format( String_Type::FORMAT_HEX ) ->required() ->description( 'A hex colour value.' ) ), ), ) );
REST Route Arguments
use PinkCrab\WP_Rest_Schema\Argument\String_Type; use PinkCrab\WP_Rest_Schema\Argument\Integer_Type; use PinkCrab\WP_Rest_Schema\Parser\Argument_Parser; register_rest_route( 'my/v1', '/search', array( 'methods' => 'GET', 'callback' => 'handle_search', 'args' => Argument_Parser::for_route( String_Type::field( 'query' )->required()->min_length( 1 ), Integer_Type::field( 'page' )->minimum( 1 )->default( 1 ), String_Type::field( 'order' )->expected( 'asc', 'desc' )->default( 'desc' ) ), ) );
Full Item Schema (for WP_REST_Controller::get_item_schema())
use PinkCrab\WP_Rest_Schema\Schema; use PinkCrab\WP_Rest_Schema\Argument\String_Type; use PinkCrab\WP_Rest_Schema\Argument\Integer_Type; public function get_item_schema() { return Schema::on( 'post' ) ->description( 'A blog post object.' ) ->integer_property( 'id', function( Integer_Type $id ) { return $id->readonly() ->description( 'Unique identifier.' ) ->context( 'view', 'edit', 'embed' ); } ) ->string_property( 'title', function( String_Type $t ) { return $t->required() ->description( 'The post title.' ) ->context( 'view', 'edit' ); } ) ->string_property( 'status', function( String_Type $s ) { return $s->expected( 'publish', 'draft', 'pending' ) ->context( 'view', 'edit' ); } ) ->additional_properties( false ) ->to_array(); }
Nested Object with Array
use PinkCrab\WP_Rest_Schema\Argument\Object_Type; use PinkCrab\WP_Rest_Schema\Argument\String_Type; use PinkCrab\WP_Rest_Schema\Argument\Integer_Type; use PinkCrab\WP_Rest_Schema\Argument\Array_Type; Object_Type::field( 'metadata' ) ->string_property( 'title', fn( String_Type $t ) => $t->required() ) ->integer_property( 'score', fn( Integer_Type $i ) => $i->minimum( 0 )->maximum( 100 ) ) ->array_property( 'tags', fn( Array_Type $a ) => $a->string_item()->unique_items() ) ->additional_properties( false )
Documentation
| Page | Description |
|---|---|
| Argument (Base Class) | Shared methods available on all types: description, default, required, readonly, title, format, expected, context, validation, sanitization, union types, and all constants |
| String Type | String_Type — minLength, maxLength, pattern |
| Number Types | Number_Type and Integer_Type — minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf |
| Array Type | Array_Type — typed items, minItems, maxItems, uniqueItems, element relationships |
| Object Type | Object_Type — properties, additionalProperties, patternProperties, minProperties, maxProperties, element relationships |
| Schema Builder | Top-level Schema class for building get_item_schema() output |
| Parser | Argument_Parser — converting builders to arrays for WordPress |
Perique Integration
This library can be used with the Perique Registerable library:
$meta_data = ( new Meta_Data( 'fixed_in' ) ) ->post_type( 'post' ) ->type( 'string' ) ->rest_schema( Argument_Parser::for_meta_data( String_Type::field( 'fixed_in' ) ->min_length( 10 ) ->max_length( 42 ) ->required() ->description( 'Required string, 10-42 chars.' ) ) );
License
MIT License
http://www.opensource.org/licenses/mit-license.html
Change Log
- 1.0.0-RC1 - Added Schema builder, readonly/title support, field() alias, for_route() helper, additionalProperties redesign, FORMAT_URI fix, PHPStan level 9, WPCS 3, PHP 8.0+/WP 6.6+
- 0.1.0 - Initial version