Hand-written validation in a REST callback, when the argument definition can do it and produce documentation at the same time.
register_rest_route( 'turkerdev/v1', '/products', array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'turkerdev_list_products',
'permission_callback' => '__return_true',
'args' => array(
'per_page' => array(
'type' => 'integer',
'default' => 20,
'minimum' => 1,
'maximum' => 100,
'sanitize_callback' => 'absint',
),
'status' => array(
'type' => 'string',
'enum' => array( 'draft', 'publish' ),
),
),
) );
The argument schema validates before the callback runs, returns a properly shaped 400 with the offending parameter named, and appears in the endpoint’s OPTIONS response — three things the hand-written version did badly or not at all. permission_callback being explicitly __return_true rather than absent is the detail worth insisting on: an omitted one is a notice and a route anybody can call.