A fluent PHP builder for WordPress REST API JSON schemas. Converts verbose nested array definitions into clean, chainable method calls.
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.' )
),
),
) );$ composer require pinkcrab/wp-rest-schemaRequirements: PHP >= 8.0 | WordPress >= 6.6
| 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(), number_item(), integer_item(), boolean_item(), array_item(), null_item(), object_item(), min_items(), max_items(), unique_items(). Plus item-relationship toggles any_of() / one_of() (no args — change how multiple items combine; default is allOf) |
| Object | Object_Type |
string_property(), number_property(), integer_property(), boolean_property(), null_property(), array_property(), object_property(), additional_properties(bool), additional_properties_schema(Argument), min_properties(), max_properties(), required_properties(string ...), plus typed pattern-property variants string_pattern_property() / number_pattern_property() / … / object_pattern_property() (no flat pattern_properties() method) |
| OneOf | One_Of_Type |
variant( Argument ) — schema-root oneOf combinator (exactly one variant must match) |
| AnyOf | Any_Of_Type |
variant( Argument ) — schema-root anyOf combinator (any variant matches) |
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, accepts mixed), context, validation, sanitization, arg_options (WP controller pass-through), and union types. See Argument (Base Class) for details.
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.' )
),
),
) );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' )
),
) );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();
}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 )| 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 |
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.' )
)
);http://www.opensource.org/licenses/mit-license.html
- 1.0.0 - Combinators (
One_Of_Type/Any_Of_Type), null/falsy defaults, array items last-wins,arg_options,required_properties, mixed enums,Schema::get_context_param(), output-keys canary test; deprecatedname()andall_of(). - 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
