Headless Wordpress, Is there a way to access data in wp_options table as REST endpoint?

1.7k views Asked by At

Wordpress has an awesome REST API interface. https://developer.wordpress.org/rest-api/reference/

But the content in wp_options table seems to be missing REST support. Is there a way to access the content in wp_otions table as REST endpoint via plugins?. Thanks.

1

There are 1 answers

3
Xhynk On BEST ANSWER

There is the settings endpoint, but it only contains a surprisingly limited amount of them it seems.

This is something you could very easily do yourself though. I'm not sure if any plugins do it, but I also wouldn't recommend a plugin for something that can be done with less than 20 lines of code.

You just need to register a route using register_rest_route() on the rest_api_init hook, and pass it a callback function. You can drop code like this in your functions.php file or create a Must Use Plugin and drop the code in there, either way.

add_action( 'rest_api_init', function () {
    register_rest_route( 'my-custom-route/v1', '/opt/', array(
        'methods' => 'GET',
        'callback' => 'get_rest_option',
        //'permission_callback' => function () {
        //  return current_user_can( 'administrator' );
        //}
    ) );
} );

function get_rest_option( $data ) {
    return get_option( $data['option_name'] );
}

The above will give you access to whatever option you want by accessing:

/wp-json/my-custom-route/v1/opt/?option_name=siteurl

I went ahead and dropped an example on a site of mine:

https://xhynk.com/content-mask/wp-json/my-custom-route/v1/opt/?option_name=blogname https://xhynk.com/content-mask/wp-json/my-custom-route/v1/opt/?option_name=siteurl

However, this will potentially expose anything in your options table. I went ahead and commented out the permission_callback so that any person, signed in or not, can access it. However, I also added a check like this:

function get_rest_option( $data ) {
    if( $data['option_name'] === 'siteurl' || $data['option_name'] === 'blogname' ){
        return get_option( $data['option_name'] );
    } else {
        return 'Unauthorized. Use `siteurl` or `blogname`';
    }
}

You can see that home will fail: https://xhynk.com/content-mask/wp-json/my-custom-route/v1/opt/?option_name=home

I would recommend adding in a valid array of options, or using the permission_callback in order to lock it down a bit. You could even have an access key instead, and keep that key secret. Either way, be aware of the security implications of exposing your entire wp_options table, and take some sort of preventative measure!