Building Wordpress REST APIs is relatively easy thanks to this plugin and other packages out there. But sometimes you need just a little more control than existing solutions give you.
There was a nice challenge in my latest client project: a WordPress site with multiple Custom Post Types and heavy usage of Advanced Custom Fields should now provide an interface for a mobile application.
WordPress itself and the REST API needed to be on the same host. So I thought it would be appropriate to use the database as the actual interface between API and WP. With this in mind I came across a package called Corcel. This package is based on Eloquent itself and offers a Laravel-Style API to fetch data from a WordPress database. So I decided to setup a clean Lumen install and try it out.
Corcel feels familiar, works great and as expected. It’s in heavy development but seems stable enough for production use. However, when I returned the output as a JSON view for the first time I got something like this:
Uhhh, this is ugly. WordPress and the way it stores and handles data is not what I’m used to in the Laravel universe. So I created a small package called mikado to filter and remap the Corcel data to a format I like (and hopefully the actual API consumers too).
Pull in the package with composer by adding the following to your
composer.json and run
composer install afterwards:
The package was tested with Corcel only, but it should be compatible with other Eloquent models.
If you want to use actual WordPress data, also pull in Corcel:
Fetch your data with Corcel
First, we need to connect to our WordPress database:
I’ve got a multisite setup, so I had to put this into a
BaseController to set the proper prefix by a routing parameter. You should probably put this into your
Time to fetch our first data, shall we?
Take a look at the Corcel documentation for the whole public API. There are some useful examples for Posts, Pages, Custom Post Types, Taxonomies, Meta, Attachments and more.
Now we reached the point we were before: this ugly WordPress-style data. Let’s configure mikado and make it nice.
If you’re using Laravel/Lumen you can use mikados ServiceProvider that automagically creates everything for you.
config/app.php and add the following:
… and this:
Publish the example config now by running:
bootstrap/app.php and add the following to the ‘Register Service Provider’ section:
.. and this to the ‘Register Container Bindings’ section:
Copy the contents of
vendor/kriskbx/mikado/config to the
config folder in your project root.
mikado <3 Corcel
To add mikados functionality to Corcel we should extend it:
To get this example working, we need to create our very first configuration file. Just rename the just published
wordpresspost.php. The filename must match the identifier we pass to the
Open the configuration file in your editor:
We got a simple array for every Formatter that comes with mikado. Just paste in your configuration and you’re done.
You can run the formatting now by simply calling the above query scope:
Pretty straightforward, hu? Let’s take a look at the array-structure the Formatters except:
WordPress meta looks like this:
The MetaFormatter takes an array like this:
and creates this:
The keys in the given array will be compared with
meta_key. If there’s a match, a new property with the name of the given value will be created. The value of the new property will be set to
meta_value. The whole
meta will be deleted after the process.
You can also provide regular expressions as keys. This ensures that even the ACF Repeater Field works:
I’m using a ‘dot’ syntax to specify the array structure within a string. If you’re using Laravel this should be familiar.
The RemapFormatter remaps or better renames and unsets properties:
This looks a lot cleaner. Nice!
The RemapFormatter also uses the ‘dot’ syntax and handles regular expressions as well:
Let’s filter some properties, shall we:
Guess, what it does. You’re right: it filters the whole data and just returns the specified properties:
Not only for Eloquent
The package was designed to work with Eloquent. But you can also use it with any other data. It works with all arrays and objects, at least phpspec says that.
This example should get you started:
Create a new Manager instance, add some Formatters to it und finally run the format method and provide your data.
Note: mikado can’t figure out if your given data is an array of objects or a single object. If you’re passing an array of objects or any other data to
Manager->format($data, true) make sure to set the second argument to true.
Limitations & issues
There’s a lot of looping going on in this package. You should use caching to keep your Server responsive and healthy. After all performance isn’t that bad. I optimized pretty everything when I wrote the tests.
I hope you had some fun reading this article or using the package. At least I had fun writing the article and creating the package.
If you want to help me keep this thing stable or add more functionality, head over to GitHub. I’m looking forward to some pull-requests.