WP REST Registration

The WordPress REST API is the new way for plugins, themes and the frontend in WordPress to contact the backend to retrieve or update information. It’s already a lot easier than dealing with the labyrinthine code required to use admin-ajax, but there’s still a fair amount of boilerplate code involved.

Here at evoMark, we’re firm believers in DRY (Don’t Repeat Yourself) coding, so we created a system to (1) utilise an object-orientation approach to declaring our routes, and (2) automatically scour allocated directories to register those routes. Ideally we wanted to just create a new route class, drop it in a directory and it would instantly be available to our theme and plugins.

So that’s what we did.

Installation

At the moment, WP REST Registration is only available via the standard Packagist repository, so you’ll need to create a composer.json file at the root of your plugin/theme. From there, run:

composer require evo-mark/evo-wp-rest-registration

This would also be a good place to set up your PSR-4 autoloading for your REST route controllers. Go into the composer.json file and add this at this level:

{
"autoload": {
"psr-4": {
"MyPluginNamespace\\": "src/"
}
}
}

Now, composer’s autoloader will automatically scan a src file in your plugin/theme and associate the root level namespace “MyPluginNamespace” with it.

The final installation step is to open your plugin’s entry file or your theme’s functions.php file and require the autoload file:

<?php
require_once "vendor/autoload.php";

This will register any dependencies (like this package) and also all of your classes inside your src folder (if you named them correctly).

Registering your routes

You can register an entire directory of routes with just one command.

<?php
use EvoWpRestRegistration\RestApi;
new RestApi([
'namespace' => 'MyPlugin\\RestApi\\',
'version' => 1,
'directory' => __DIR__ . '/src/RestApi',
'base_url' => 'my-plugin'
]);

The above example will load route files from the directory given with the base URL of https://yourdomain.com/wp-json/my-plugin/v1/

RestApi props

The RestApi constructor above accepts a single associative array as an argument with four possible properties inside:

PropertyTypeRequiredDescriptionDefault
namespacestringyesThe root namespace of your route classes<empty>
directorystringyesThe root directory containing your route classes<empty>
versionintnoThe version of your REST API to register1
base_urlstringyesThe base URL used for your routes<empty>

Anatomy of a route class

Inside your chosen directory, you can now start to define your route classes

1<?php
2namespace MyPlugin\RestApi;
3
4use WP_REST_Request;
5use EvoWpRestRegistration\BaseRestController;
6
7defined('ABSPATH') or exit;
8
9class PingGet extends BaseRestController
10{
11 protected $path = 'ping';
12 protected $methods = 'GET';
13 // From ^3.0.0 endpoints must opt-in to be shown in the REST index at /wp-json
14 protected bool $indexed = true;
15
16 public function authorise()
17 {
18 return current_user_can('manage_options');
19 }
20
21 public function handler(WP_REST_Request $request)
22 {
23 wp_send_json_success([
24 'status' => 'success',
25 'response' => 'pong',
26 ]);
27 }
28}

Validation

You can add a rules property to your controller to automatically validate parameters.

1<?php
2namespace MyPlugin\RestApi;
3
4use WP_REST_Request;
5use EvoWpRestRegistration\BaseRestController;
6
7defined('ABSPATH') or exit;
8
9class CheckSomevar extends BaseRestController
10{
11 protected $path = 'check-somevar';
12 protected $methods = 'POST';
13 protected $rules = [
14 'somevar' => ['required','numeric']
15 ]
16
17 public function handler()
18 {
19 $validated = $this->validated();
20
21 // Only fields with rules that have been passed will be on your validated parameters.
22
23 // Failure will result in a WP_Error('validation_failed') error being returned (HTTP status 400)
24
25 wp_send_json_success([
26 'status' => 'success',
27 'response' => 'somevar was a number',
28 ]);
29 }
30}

Available validation rules

Rule nameArgArg 2Arg 3Description
requiredParam is required
nullableRemaining rules are skipped if null value
sometimesRemaining rules are skipped if param not set
booleanMust be either true or false
stringMust be a string
emailMust be a valid email address
urlrequire (path,query)as Arg 1Must be a valid URL
jsonMust be a decodable JSON string
numericMust be a numeric value (int or float)
arrayMust be an array
inval1val2 etcValue must be one of passed args
not_inval1val2 etcValue must not be one of the passed args
existstable (no prefix)columnValue must exist on the given table/column
uniquetable (no prefix)columnexclude idValue must not exist on the given table/column
minminimumMinimum value for field, or size in KB for files
maxmaximumMaximum value for field, or size in KB for files
lowercaseMust not contain any uppercase characters
uppercaseMust not contain any lowercase characters
starts_withval1val2 etcMust start with one of the provided args
ends_withval1val2 etcMust end with one of the provided args
alpha_underscoreCan only contain alphabetical characters or underscores
alpha_dashCan only contain alphabetical characters or hyphens
alpha_numCan only contain alpha-numeric characters
hex_colourValue must be a valid hexadecimal colour value
fileValue must be a file object
extensionsval1val2 etcFile must have an extension matching one of the passed args
mimetypesval1val2 etcFile must have mime-type matching one of the passed args

Custom validation messages

By default, WP REST Registration will use the following validation error messages:

[
'required' => '%param% is required',
'string' => '%param% must be a string',
'numeric' => '%param% must be numeric',
'array' => '%param% must be an array',
'boolean' => '%param% must be true or false',
'email' => 'Valid email address is required',
'unique' => '%value% already exists as a %param%',
'exists' => '%param% must exist on %args%',
'in' => '%param% must be one of %args%',
'not_in' => '%param% must be not be any of %args%',
'json' => '%param% must be a valid JSON string',
'url' => '%param% must be a valid URL',
'min' => '%param% must be at least %args%',
'max' => '%param% must be no more than %args%',
'lowercase' => '%param% must be lowercase',
'uppercase' => '%param% must be uppercase',
'starts_with' => '%param% must start with one of the following: %args%',
'ends_with' => '%param% must end with one of the following: %args%',
'alpha_underscore' => '%param% can only contain letters and underscores',
'alpha_dash' => '%param% can only contain letters and hyphens',
'alpha_num' => '%param% can only contain letters and numbers',
'hex_colour' => '%param% must be a hex colour',
'file' => '%param% must be a valid file',
'extensions' => '%param% must be a file with extension of %args%',
'mimetypes' => '%param% must be a file with a mime type of %args%'
];

If you want to override one or more, you can simply includes a messages property on your route class. These will be merged in with the defaults, e.g.

1class CheckSomevar extends BaseRestController
2{
3 protected $rules = [
4 'somevar' => ['required','numeric']
5 ]
6
7 protected $messages = [
8 'required' => 'Required!'
9 ];
10
11 public function handler()
12 {
13 $validated = $this->validated();
14
15 // do stuff
16 }
17}

At present, your message can contain %param%, %value% or %args%, which will be replaced by their respective values.

Feedback & issues

If you come accross any issues in WP REST Registration, or have any suggestions as to how we can make it better, please use the discussion or issues tab on the Github repository respectively.

We’d also appreciate any stars you have spare on the repo.

Part of evoMark's contribution to Free and Open Source Software (FOSS)

To read more about evoMark and our open-source software, head to our Open-Source Software page

composer require evo-mark/evo-wp-rest-registration
Get in Touch

Get in touch with us today 01202 790300

monday 09:00 - 17:00
tuesday 09:00 - 17:00
wednesday 09:00 - 17:00
thursday 09:00 - 17:00
friday 09:00 - 16:00
saturday closed
sunday closed