rest_no_route custom route

The problem is, you are calling a static method from inside of a non-static method. The following will work.

class theme_Rest_Routes extends WP_REST_Controller{

    public static function init() {
        $instance = new self();
        add_action( 'rest_api_init', array( $instance, 'register_routes' ) );
    }

    public function register_routes() {
        register_rest_route( 'theme/v1', '/menu/', array(
            'methods' => 'GET',
            'callback' => array( $this, 'theme_rest_menu' ) )
        );
    }

    public function theme_rest_menu( $request ) {
        return wp_get_nav_menu_items( 'menu' );
    }
}
theme_Rest_Routes::init();

Code Improvement

You should not hook into rest_api_init from within the controller class itself, rather call it from an external class/function. Also class name should use capitalized words. As like below:

function theme_register_rest_apis() {
    $controller = new Theme_Rest_Routes();
    $controller->register_routes();
}
add_action( 'rest_api_init', 'theme_register_rest_apis' );

class Theme_Rest_Routes extends WP_REST_Controller{

    public function register_routes() {
        register_rest_route( 'theme/v1', '/menu/', array(
            'methods' => 'GET',
            'callback' => array( $this, 'theme_rest_menu' ) )
        );
    }

    public function theme_rest_menu( $request ) {
        return wp_get_nav_menu_items( 'menu' );
    }
}