Skip to content
This repository was archived by the owner on Sep 24, 2018. It is now read-only.
This repository was archived by the owner on Sep 24, 2018. It is now read-only.

Recommended way to create custom endpoint with pagination #2347

Description

@wujekbogdan

Hi,

I'm new to WP-API, I read the documentation and I found in the Adding Custom Endpoints section that the recommended way to add new endpoints is to extend the WP_REST_Controller class. But the example given in the documentation doesn't explain how to create endpoints supporting paginated results.

Basically, I'd like to add a new endpoint that works exactly like the default ones, but modify the query and add some additional parameters for post meta values and taxonomies.

I've studied the source code a bit and I found that instead of extending the low level WP_REST_Controller class I could probably extend the WP_REST_Posts_Controller class and override: register_routes and prepare_items_query methods.

Does it make sense? Is it a proper way of adding custom endpoints with pagination?

It would be great if you improved the the documentation and provided some examples. The issue I'm trying to deal with sounds like a quite common use case for custom endpoints.

Thanks!

// EDIT:

I've prepared a basic example. It seems to work fine:

// Extend the `WP_REST_Posts_Controller` class
class My_Custom_Controller extends WP_REST_Posts_Controller
{

    // Override the register_routes() and add '/my_custom_route'
    public function register_routes()
    {
        register_rest_route($this->namespace, '/my_custom_route', [
            [
                'methods' => WP_REST_Server::READABLE,
                'callback' => [$this, 'get_items'],
                'permission_callback' => [$this, 'get_items_permissions_check'],
                'args' => $this->get_collection_params(),
            ],
            'schema' => [$this, 'get_public_item_schema'],
        ]);
    }

    // Override the `prepare_items_query` method in order to add custom query arguments
    protected function prepare_items_query($prepared_args = [], $request = null)
    {
        // Call the parent class method
        $query_args = parent::prepare_items_query($prepared_args, $request);

        // Extend custom query arguments
        $custom_query_args = [
            'tax_query' => [
                'relation' => 'AND',
                [
                    'taxonomy' => 'tags',
                    'field' => 'slug',
                    'terms' => ['tag1'],
                ],
                [
                    'taxonomy' => 'type',
                    'field' => 'slug',
                    'terms' => ['landscape'],
                ],
            ],
        ];

        // Return a merged array including default and custom arguments
        return array_merge($query_args, $custom_query_args);
    }

}

// Create an instance of `My_Custom_Controller` and call register_routes() methods
add_action('rest_api_init', function () {
    $myProductController = new My_Custom_Controller('my_post_type');
    $myProductController->register_routes();
});

Additionally, we could add custom query vars:

add_filter('rest_query_vars', function ($args) {
    $args = array_merge($args, ['my_custom_var']);
    return $args;
});

And custom filters for the query var

add_filter('rest_query_var-my_custom_var', function ($var) {
    // Do something with $var
    return $var;
});

And of course, register the custom parameter using the register_rest_route() function in the register_routes() method. Then use it in the $custom_query_args array.

Activity

  1. danielbachhuber commented on Mar 7, 2016

    @danielbachhuber
    Member

    @wujekbogdan The code you've supplied seems like it should work fine. Subclassing the Posts controller for your own needs is acceptable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions