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:
-
With permalinks enabled, you can get a pretty endpoint URL (for the above route) like
https://example.com/wp-json/uheme/v1/menu -
But regardless permalinks enabled or disabled, the endpoint is also accessible at
index.php?rest_route=<route>as inhttps://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.