As I said in the comments, since it’s a custom endpoint, you could just cancel the post creation via the main callback, i.e. something like so:
'callback' => function () {
if ( some condition ) {
// create the post
} else {
// return existing post or something else
}
}
And here’s an example where the POST endpoint creates a published post (of the post
type), but only if there’s no existing published post having the same title as specified in a parameter named title
:
Note: When registering custom REST routes, use your own namespace (e.g. my-namespace/v1
) and not wp/v2
.
add_action( 'rest_api_init', function() {
register_rest_route( 'my-namespace/v1', '/foobar', array(
'methods' => 'POST',
'callback' => function ( $request ) {
$posts = get_posts( array(
'post_type' => 'post',
'title' => $request['title'],
'fields' => 'ids',
) );
if ( ! empty( $posts ) ) {
return new WP_Error(
'rest_post_exists',
'There is already a post with the same title.',
array( 'status' => 400 )
);
}
return wp_insert_post( array(
'post_type' => 'post',
'post_title' => $request['title'],
'post_status' => 'publish',
) );
},
'permission_callback' => function ( $request ) {
return current_user_can( 'publish_posts' );
},
'args' => array(
'title' => array(
'type' => 'string',
'required' => true,
'validate_callback' => function ( $param, $request ) {
if ( ! preg_match( '/[a-z0-9]+/', $param ) ) {
return new WP_Error(
'rest_invalid_title',
'Please enter a valid title for the post.',
array( 'status' => 400 )
);
}
return true;
}
),
),
) );
} );
However, note that if foobar
is actually a custom post type, then when registering the post type (see register_post_type()
), you could actually set show_in_rest
to true
and then set rest_controller_class
to the name of a custom REST controller class like the one here.