Wordpress - Wordpress Rest API custom endpoint optional param

You should put the named parameters of the route regex into an optional capturing group:

register_rest_route( 'api', '/animals(?:/(?P<id>\d+))?', [
   'methods' => WP_REST_Server::READABLE,
   'callback' => 'get_animals',
   'args' => [
        'id'
    ],
] );

The second parameter is simply a regex, thus you can use normal regex logic to make it more complex


There may be a way to do it with one register_rest_route function call, I do not know how to do that and it would be ideal. However, duplicating the register_rest_route function call in the hooked method will do what you want.

register_rest_route( 'api', '/animals/', [
   'methods' => WP_REST_Server::READABLE,
   'callback' => 'get_animals'
] );

register_rest_route( 'api', '/animals/(?P<id>\d+)', [
   'methods' => WP_REST_Server::READABLE,
   'callback' => 'get_animals',
   'args' => [
        'id'
    ],
] );

It the get_animals method you'll want to have conditions that handle each case. One for if the id arg is set, and the fallback checks for $_GET variables.