GeneratorsCoreREST Route

REST Route Generator

Namespaced endpoints with a real args schema, sanitise and validate callbacks, and a permission callback that is never just __return_true by accident.

items-route.php
Saved just now
The endpoint
/wp-json/myplugin/v1/items
Methods
Each method gets its own callback.
Who can call it
permission_callback is required — omitting it throws a notice.
Readable by anyone and cached by proxies. Never expose private data or write operations here.
Arguments
Becomes the args schema — WordPress validates before your callback runs.
absint() → rest_validate_request_arg() · min/max
sanitize_text_field() → rest_validate_request_arg()
Extras
Also register a REST field
Adds a register_rest_field() example that extends the core post response.
Send cache headers
Adds a rest_post_dispatch filter with Cache-Control. Public GET routes only.
Paste into a plugin, an mu-plugin, or a functionality plugin.
// Generated with WP CodeKit — powered by GrowQuest (https://growquest.io).
/**
 * Register the /items endpoint.
 */
function myplugin_register_items_route() {
	register_rest_route(
		'myplugin/v1',
		'/items',
		array(
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => 'myplugin_items_get',
				'permission_callback' => 'myplugin_items_permission',
				'args'                => array(
					'per_page' => array(
						'description'       => __( 'How many items to return.', 'textdomain' ),
						'type'              => 'integer',
						'default'           => 10,
						'minimum'           => 1,
						'maximum'           => 50,
						'sanitize_callback' => 'absint',
						'validate_callback' => 'rest_validate_request_arg',
					),
					'search' => array(
						'description'       => __( 'Optional search term.', 'textdomain' ),
						'type'              => 'string',
						'sanitize_callback' => 'sanitize_text_field',
						'validate_callback' => 'rest_validate_request_arg',
					),
				),
			),
		)
	);
}
add_action( 'rest_api_init', 'myplugin_register_items_route' );

/**
 * Permission check for /items.
 *
 * @return true|WP_Error
 */
function myplugin_items_permission() {
	return true;
}

/**
 * GET /items
 *
 * @param WP_REST_Request $request Request object.
 * @return WP_REST_Response|WP_Error
 */
function myplugin_items_get( $request ) {
	$per_page = $request->get_param( 'per_page' );
	$search = $request->get_param( 'search' );

	$query = new WP_Query(
		array(
			'post_type'      => 'post',
			'post_status'    => 'publish',
			'posts_per_page' => $per_page,
			'no_found_rows'  => true,
		)
	);

	$items = array_map(
		static function ( $post ) {
			return array(
				'id'    => $post->ID,
				'title' => get_the_title( $post ),
				'link'  => get_permalink( $post ),
			);
		},
		$query->posts
	);

	return rest_ensure_response( $items );
}