REST API
WP Bones provides a simple way to create your own REST API. You may use the WordPress REST API as well.
You'll find more info here (opens in a new tab)
Configuration
First of all, we have added a new api.php
configuration file to the config
folder.
You'll find some useful settng to handle the embeded WordPress Rest API and your custome own endpoints.
<?php
/*
|--------------------------------------------------------------------------
| WordPress REST API configuration
|--------------------------------------------------------------------------
|
| Here is where you can set up the WordPress REST API features.
|
*/
return [
// embedded wp-json-server
'wp' => [
'require_authentication' => false, // will affect all routes.
],
// your custom rest api
'custom' => [
'path' => '/api',
'enabled' => true,
],
// authentication
'auth' => [
// embed basic authentication handler
'basic' => true,
],
];
Create your first API
To create your custom API, you have to create a new folder into /api
in the root of your plugin.
You may change the name of your folder, but you'll have to change the path
in the api.php
configuration file.
The main folder will be the vendor
. Usually, into the vendor folder you'll create the version
folder as well.
For example, you may create
Routing
Now, we can start to create the Rest API route by adding a new file in the our structure.
For example, we'll use route.php
- route.php
Let's see a simple implementation of route.php
use WPKirk\WPBones\Routing\API\Route;
Route::get('/example', function () {
return 'Hello World!';
});
You may use your browser to test /api/vendor/v1/example
route.
HTTP Methods
The Route
class supports the following HTTP methods: get
, post
, put
, patch
, delete
In short, the same supported by the WordPress REST API and defined in the WP_REST_Server
class.
use WPKirk\WPBones\Routing\API\Route;
Route::post('/example', function () {
return 'Hello World!';
});
Instead of use the static method Route::get()
, Route::post()
, and so on, you can use the ::request()
instead. You will be able to use multiple HTTP verbs at the same time.
use WPKirk\WPBones\Routing\API\Route;
Route::request('get', '/get_request', function () {
return 'Hello World!';
});
// HTTP verb is case insensitive
Route::request('GET', '/get_request', function () {
return 'Hello World!';
});
// you may use both strings and arrays
Route::request(['get'], '/get_request', function () {
return 'Hello World!';
});
// you may use multiple HTTP verbs
Route::request(['get', 'POST'], '/multiple', function () {
return 'Hello World!';
});
WP_REST_Request injection
You will be able to get the WP_REST_Request
object from the function used in the Route
class.
use WPKirk\WPBones\Routing\API\Route;
Route::get('/example_args', function (\WP_REST_Request $request) {
$value = var_export($request, true);
/**
* // You can access parameters via direct array access on the object:
* $param = $request['some_param'];
*
* // Or via the helper method:
* $param = $request->get_param( 'some_param' );
*
* // You can get the combined, merged set of parameters:
* $parameters = $request->get_params();
*
* // The individual sets of parameters are also available, if needed:
* $parameters = $request->get_url_params();
* $parameters = $request->get_query_params();
* $parameters = $request->get_body_params();
* $parameters = $request->get_json_params();
* $parameters = $request->get_default_params();
*
* // Uploads aren't merged in, but can be accessed separately:
* $parameters = $request->get_file_params();
*/
return 'Hello World!';
});
JSON Response
Of course, you may return a JSON response by using the WordPress wp_send_json()
function.
use WPKirk\WPBones\Routing\API\Route;
// json response
Route::get('/example_json', function () {
wp_send_json(["tag" => "v1.0.0"]);
});
You may use also the response()
static method provides by the Route
class.
use WPKirk\WPBones\Routing\API\Route;
// right way to use a simple response
Route::get('/example_response', function () {
return Route::response(["tag" => "v1.0.0"]);
});
Error Response
The best practice is to return a WP_Error
object.
use WPKirk\WPBones\Routing\API\Route;
// invalide example
Route::get('/invalid', function () {
return new \WP_Error('no_author', 'Invalid author', [ 'status' => 404 ]);
});
Also in this case, you may use the responseError()
static method provides by the Route
class.
use WPKirk\WPBones\Routing\API\Route;
// right way to use an error response
Route::get('/error', function () {
return Route::responseError('no_author', 'Invalid author', [ 'status' => 404 ]);
});
RestController
Of course, you may use a RestController
to handle the request. WPBones provides a simple way to create a new controller.
You may create your own controller extending the RestController
class.
For example, lets create a new controller called WPKirkV1Controller
in the wp-content/plugins/WPKirk/plugin/API/WPKirkV1Controller.php
folder.
namespace WPKirk\API;
use WPKirk\WPBones\Routing\API\RestController;
class WPKirkV1Controller extends RestController
{
public function version()
{
return $this->response(['version' => '1.0.0']);
}
}
Using the php bones make:api
Bones command, we can quickly create a RestController
.
Now, in the route.php
file, you may use the WPKirkV1Controller
.
use WPKirk\WPBones\Routing\API\Route;
// may use the same route for different methods
Route::get('/version', '\WPKirk\API\WPKirkV1Controller@version');
WP_REST_Request and vendor injection
By usign a RestController
you may get the WP_REST_Request
object and the vendor information in different ways. The first one is using the property request
of the RestController
class.
namespace WPKirk\API;
use WPKirk\WPBones\Routing\API\RestController;
class WPKirkV1Controller extends RestController
{
public function version()
{
// get the request object and log the method
logger()->debug("REQUEST get_method", $this->request->get_method());
return $this->response(['version' => '1.0.0']);
}
}
Of course, feel free to check the WordPress documentation for more information about the WP_REST_Request
object.
The second way is using inject object in method directly.
namespace WPKirk\API;
use WPKirk\WPBones\Routing\API\RestController;
class WPKirkV1Controller extends RestController
{
public function version($request)
{
// get the request object and log the method
logger()->debug("REQUEST get_method", $request->get_method());
return $this->response(['version' => '1.0.0']);
}
}
The vendor information, instead, is available in the property vendor
of the RestController
class. You will get all paths along with any version information. For instance wpkirk/v1
in our example.
namespace WPKirk\API;
use WPKirk\WPBones\Routing\API\RestController;
class WPKirkV1Controller extends RestController
{
public function version($request)
{
// get the request object and log the method
logger()->debug("Vendor", $request->vendor); // for example, "wpkirk/v1"
return $this->response(['version' => '1.0.0']);
}
}
Authentication
WPBones will add the Basic Authentication features without use the official WordPress Plugin (opens in a new tab). The Basic Authentication is based on the WordPress Basic Authentication (opens in a new tab) and the WordPress Basic Authentication Plugin (opens in a new tab).
Remember that you have to enebale this feature from api.php
configuration file.
<?php
/*
|--------------------------------------------------------------------------
| WordPress REST API configuration
|--------------------------------------------------------------------------
|
| Here is where you can set up the WordPress REST API features.
|
*/
return [
// authentication
'auth' => [
// embed basic authentication handler
'basic' => true
]
]
Options
You may add additional options to the Route
following the WordPress REST para
use WPKirk\WPBones\Routing\API\Route;
Route::get('/example', function () {
return 'Hello World!';
}, ['permission_callback' => function () {
return false;
}]);
In the above example you'll receive
{"code":"rest_forbidden","message":"Sorry, you are not allowed to do that.","data":{"status":401}}
Of course, you may do the same with the RestController
as well
use WPKirk\WPBones\Routing\API\Route;
Route::get('/version', '\WPKirk\API\WPKirkV1Controller@version', [
'permission_callback' => function () {
return false;
}]);
{"code":"rest_forbidden","message":"Sorry, you are not allowed to do that.","data":{"status":401}}
Disable the WordPress REST API
You should not disable the REST API; doing so will break WordPress Admin functionality that depends on the API being active. However, you may use a filter to require that API consumers be authenticated, which effectively prevents anonymous external access.
Anyway, you can require authentication for all REST API requests by setting the require_authentication
to true
in the configuration file.
<?php
/*
|--------------------------------------------------------------------------
| WordPress REST API configuration
|--------------------------------------------------------------------------
|
| Here is where you can set up the WordPress REST API features.
|
*/
return [
// embeded wp-json-server
'wp' => [
'require_authentication' => true
],
]
The above setting will affect all routes. From a browser request, you won't receive the error message if you're logged in.