Igor Simic
6 years ago

Wordpress REST API custom endpoint pagination


In this example i will show you how to create custom route for posts queried by tag and use pagination for end result. For paginating query result it is not recommended to use get_posts() method but WP_Query class.

so let's create custom route:

add_action( 'rest_api_init', function () {

          register_rest_route( 'myspace/v1/', 'get-by-tag/(?P<slug>[a-z0-9]+(?:-[a-z0-9]+)*)/(?P<page>[1-9]{1,2})', array(
                'methods' => WP_REST_Server::READABLE,
                'callback' => 'myspace_get_posts_by_tag',
                'args' => array(
                    'slug' => array (
                        'required' => true
                    ),
                    'page' => array (
                        'required' => true
                    ),
                    
                )
            ) );

        } );
In our example we can call this url with pagination number at the end: myspace/v1/get-by-tag/tag-name/2

Next, let's create callback method:
        function myspace_get_posts_by_tag(WP_REST_Request $request){
          // get slug and page number
            $slug = $request['slug'];
            $page = $request['page'];
             
         // get tag -> more info here: https://www.coditty.com/code/wordpress-rest-api-get-posts-by-tag 
            $term = get_term_by('slug', $slug, 'post_tag');

            $args = array(
                'tag__in'           => $term->term_id,
                'posts_per_page'    => $posts_per_page,
                'paged'             => $page,
                'orderby'           => 'date',
                'order'             => 'desc',
            );
         // use WP_Query to get the results with pagination
            $query = new WP_Query( $args ); 
        
         // if no posts found return 
            if( empty($query->posts) ){
                return new WP_Error( 'no_posts', __('No post found'), array( 'status' => 404 ) );
            }
             
        // set max number of pages and total num of posts
            $max_pages = $query->max_num_pages;
            $total = $query->found_posts;

            $posts = $query->posts;
        
       // prepare data for output
            $controller = new WP_REST_Posts_Controller('post');

            foreach ( $posts as $post ) {
                $response = $controller->prepare_item_for_response( $post, $request );
                $data[] = $controller->prepare_response_for_collection( $response );  
            }
 
       // set headers and return response      
            $response = new WP_REST_Response($data, 200);

            $response->header( 'X-WP-Total', $total ); 
            $response->header( 'X-WP-TotalPages', $max_pages );
   
            return $response;
        }
In our example we are returning in header total number of pages and total  number of posts