1

I'm currently making a custom API endpoint for a site that I'm building, which works absolutely fine aside from this issue with author ID's.

If I do a GET request to website.local/wp-json/wp/v2/podcasts it returns valid JSON of all of the podcasts Custom Post Type. If I do a GET request to website.local/wp-json/wp/v2/podcasts?author=1 it also returns valid JSON of all of the podcasts Custom Post Type - no problems here.

The problem however comes from some other code that I'm writing, I'm trying to do this in a custom function:

$server = rest_get_server();
$podcastsRequest = new WP_REST_Request( 'GET', '/wp/v2/podcasts?author=1');
$podcastsResponse = rest_do_request( $podcastsRequest );
$podcastsData = $server->response_to_data( $podcastsResponse, false );

When I run it in Postman I get the following response:

{
    "code": "rest_no_route",
    "message": "No route was found matching the URL and request method.",
    "data": {
        "status": 404
    }
}

If I do this call internally inside the function, it works fine:

$server = rest_get_server();
$podcastsRequest = new WP_REST_Request( 'GET', '/wp/v2/podcasts');
$podcastsResponse = rest_do_request( $podcastsRequest );
$podcastsData = $server->response_to_data( $podcastsResponse, false );

I cannot work out why it's producing that error when a direct call to it works fine?

EDIT: To give more context, this is the function I'm using:

function get_all_posts(WP_REST_Request $request){
    $server = rest_get_server();

    if($request->get_param('id')){
        // $author = $request->get_param('author');
        $podcastsRequest = new WP_REST_Request( 'GET', '/wp/v2/podcasts?author=1');
        // $articlesRequest = new WP_REST_Request( 'GET', '/wp/v2/articles?author=1');
        // $webinarsRequest = new WP_REST_Request( 'GET', '/wp/v2/webinars?author=1');
        // $expertInterviewsRequest = new WP_REST_Request( 'GET', '/wp/v2/expert-interviews?author=1');
        // $guidesRequest = new WP_REST_Request( 'GET', '/wp/v2/guides?author=1');
    } else {
        $podcastsRequest = new WP_REST_Request( 'GET', '/wp/v2/podcasts' );
        $articlesRequest = new WP_REST_Request( 'GET', '/wp/v2/articles' );
        $webinarsRequest = new WP_REST_Request( 'GET', '/wp/v2/webinars' );
        $expertInterviewsRequest = new WP_REST_Request( 'GET', '/wp/v2/expert-interviews' );
        $guidesRequest = new WP_REST_Request( 'GET', '/wp/v2/guides' );
    }

    $podcastsResponse = rest_do_request( $podcastsRequest );
    $podcastsData = $server->response_to_data( $podcastsResponse, false );


    $articlesResponse = rest_do_request( $articlesRequest );
    $articlesData = $server->response_to_data( $articlesResponse, false );

    $webinarsResponse = rest_do_request( $webinarsRequest );
    $webinarsData = $server->response_to_data( $webinarsResponse, false );

    $expertInterviewsResponse = rest_do_request( $expertInterviewsRequest );
    $expertInterviewsData = $server->response_to_data( $expertInterviewsResponse, false );

    $guidesResponse = rest_do_request( $guidesRequest );
    $guidesData = $server->response_to_data( $guidesResponse, false );

    $merged = array_merge(
        $podcastsData,
        $articlesData,
        $webinarsData,
        $expertInterviewsData,
        $guidesData,
    );

    return $merged;
}

add_action('rest_api_init', function () {
    register_rest_route( 'wp/v2', '/all-posts', [
        'methods'  => 'GET',
        'callback' => 'get_all_posts',
    ]);
});

As I've said above, if I just use the new WP_REST_Request( 'GET', '/wp/v2/podcasts' ); endpoints, it works fine, but if I try and use new WP_REST_Request( 'GET', '/wp/v2/podcasts?author=1' ); it returns that error, despite a direct call to website.local/wp-json/wp/v2/podcasts?author=1 returning all the posts for the author.

7
  • 1
    can you share details of what you did in postman? The way your question is written implies you wrote PHP code in Postman which can't be true. Have you directly visited it in the browser to confirm manually without the use of tools and code? And that you have turned on pretty permalinks?
    – Tom J Nowell
    Feb 13, 2023 at 11:05
  • @TomJNowell Nope, no PHP in postman, I created a custom endpoint in functions.php called /all-posts which returns every post type as one array. As I said in the question, the code works when visiting the endpoints in postman, but doing /wp/v2/podcasts?author=1 instead of /wp/v2/podcasts inside WP_REST_Request completely kills the request. Going to the browser won't fix this issue Feb 13, 2023 at 11:12
  • @TomJNowell I've added more code, but this seems to be a bug with WP_REST_Request or similar? Feb 13, 2023 at 11:17
  • Got it working, I can't directly to ?author=1 in the request, I had to change it to $podcastsRequest = new WP_REST_Request( 'GET', '/wp/v2/podcasts'); $podcastsRequest->set_query_params( array( 'author' => $author )); Feb 13, 2023 at 11:48
  • hmmm, now I see your code I can see that you'll only ever be able to get the first 10 posts of each post type, none of the other parameters get passed through and you aren't using pagination headers
    – Tom J Nowell
    Feb 13, 2023 at 11:51

1 Answer 1

2

My approach to this was wrong, and I didn't understand the error properly. After taking another look at this, I was able to fix it by replacing this code:

if($request->get_param('id')){
    // $author = $request->get_param('author');
    $podcastsRequest = new WP_REST_Request( 'GET', '/wp/v2/podcasts?author=1');
    $articlesRequest = new WP_REST_Request( 'GET', '/wp/v2/articles?author=1');
    $webinarsRequest = new WP_REST_Request( 'GET', '/wp/v2/webinars?author=1');
    $expertInterviewsRequest = new WP_REST_Request( 'GET', '/wp/v2/expert-interviews?author=1');
    $guidesRequest = new WP_REST_Request( 'GET', '/wp/v2/guides?author=1');
} else {
    $podcastsRequest = new WP_REST_Request( 'GET', '/wp/v2/podcasts?author=1' );
    $articlesRequest = new WP_REST_Request( 'GET', '/wp/v2/articles?author=1' );
    $webinarsRequest = new WP_REST_Request( 'GET', '/wp/v2/webinars?author=1' );
    $expertInterviewsRequest = new WP_REST_Request( 'GET', '/wp/v2/expert-interviews?author=1' );
    $guidesRequest = new WP_REST_Request( 'GET', '/wp/v2/guides?author=1' );
}

with this code:

if($request->get_param('author')){
    $author = $request->get_param('author');

    $podcastsRequest = new WP_REST_Request( 'GET', '/wp/v2/podcasts');
    $podcastsRequest->set_query_params( array( 'author' => $author ));

    $articlesRequest = new WP_REST_Request( 'GET', '/wp/v2/articles');
    $articlesRequest->set_query_params( array( 'author' => $author ));

    $webinarsRequest = new WP_REST_Request( 'GET', '/wp/v2/webinars');
    $webinarsRequest->set_query_params( array( 'author' => $author ));

    $expertInterviewsRequest = new WP_REST_Request( 'GET', '/wp/v2/expert-interviews');
    $expertInterviewsRequest->set_query_params( array( 'author' => $author ));

    $guidesRequest = new WP_REST_Request( 'GET', '/wp/v2/guides');
    $guidesRequest->set_query_params( array( 'author' => $author ));
} else {
    $podcastsRequest = new WP_REST_Request( 'GET', '/wp/v2/podcasts');
    $articlesRequest = new WP_REST_Request( 'GET', '/wp/v2/articles');
    $webinarsRequest = new WP_REST_Request( 'GET', '/wp/v2/webinars');
    $expertInterviewsRequest = new WP_REST_Request( 'GET', '/wp/v2/expert-interviews');
    $guidesRequest = new WP_REST_Request( 'GET', '/wp/v2/guides');
}

This now works as the API endpoint isn't directly set up to match additional parameters on itself, however passing them through with set_query_params() did the job!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.