WordPress REST API register_rest_route give a 500 error

Revised answer

To other readers, another issue was the OP used the wrong route.

So make sure to make the API request to the correct route, which is a combination of the first two parameters for register_rest_route() (namespace + route base). So with register_rest_route( 'uheme/v1', '/menu' ), the route is uheme/v1/menu. Additionally:

  1. With permalinks enabled, you can get a pretty endpoint URL (for the above route) like https://example.com/wp-json/uheme/v1/menu

  2. But regardless permalinks enabled or disabled, the endpoint is also accessible at index.php?rest_route=<route> as in https://example.com/index.php?rest_route=/uheme/v1/menu

And to OP, if a callable/callback is in the form of array( __CLASS__, 'method_name' ) (or maybe 'My_Class::method_name'), then you need to define the class method as static (e.g. public static function method_name()) to prevent PHP errors. 🙂

And note that you also made a mistake with that 'method' => 'GET' which should be 'methods' => 'GET' — note the plural “methods”. For GET (request) method, that method would work because GET is the default method, but if you were only allowing POST method and you used 'method' => 'POST', then that wouldn’t work — POST would never be allowed! So once again, the correct array key is methods.


Original answer

Your original class (without extending WP_REST_Routes) worked for me, after I changed the $this to __CLASS__:

'callback' => array($this, '_rest_menu') // I changed this
'callback' => array(__CLASS__, '_rest_menu') // to this

Without that change, I got this error:

{"code":"rest_invalid_handler","message":"The handler for the route is invalid","data":{"status":500}}

So make sure you provide a valid callable/callback as the route handler. Or that be aware that in your utheme_routes() method, the $this is not available because you didn’t do something like $instance = new Uheme_Rest_Routes; $instance->init();.

Update: You can also try changing the 'method' => 'GET' to 'methods' => 'GET'. And be sure the route is /wp-json/uheme/v1/menu.