Back

WordPress as App Engine: Using the WP-JSON API

8 June 2015

Chris Jenkins

In 2013, preparing the Google Summer of Code, Ryan McCue announced he was building a formal JSON API to be included in WordPress core. This plugin would give WordPress a REST based API to content which could be accessed by third party sources. Two years later, the plugin is well on its way to inclusion, and can now be downloaded from the WordPress repository for installation on your WP site. This level of functionality will open up new windows of opportunity for WordPress developers, since it allows WordPress to essentially run as a stand alone data service. By bundling content into easy to consume JSON packages, any WordPress site can now become the back end for a multitude of app concepts.

The API returns data from the following WordPress concepts:

  • Posts
  • Pages
  • Users
  • Media
  • Taxonomies
  • Custom Post Types

The last one is the most important; since custom post types can be created for basically anything, any app concept that uses the idea of listing information (like movie times, product reviews, etc.) can use this API as its back end.

Interacting with the API is very simple; simply send a GET request at the desired endpoint:

GET http://yoursite.com/wp-json/posts/

…and the system returns a well formatted JSON package with the data in question:

{
    "ID": 1631,
    "title": "Use the New WordPress 3.5 Color Picker in a Plugin",
    "status": "publish",
    "type": "post",
    "author": {
      "ID": 1,
      "username": "rachelbaker",
      "name": "rachelbaker",
      "first_name": "",
      "last_name": "",
      "nickname": "rachelbaker",
      "slug": "rachelbaker",
      "URL": "",
      "avatar": "http:\/\/0.gravatar.com\/avatar\/634b37a53babc18a5bda19722d5b41a3?s=96",
      "description": "Full stack web developer",
      "registered": "2012-01-19T21:42:58+00:00",
      "meta": {
        "links": {
          "self": "http:\/\/rachelbaker.me\/wp-json\/users\/1",
          "archives": "http:\/\/rachelbaker.me\/wp-json\/users\/1\/posts"
        }
      }
    },
    "content": "<p>One of the many new features in <a title=\"WordPress 3.5\" href=\"http:\/\/codex.wordpress.org\/Version_3.5\">WordPress 3.5<\/a> is the Iris color picker. <a title=\"Replace Farbtastic color picker\" href=\"http:\/\/core.trac.wordpress.org\/ticket\/21206\">\u00a0Iris replaces the, now deprecated, Farbtastic<\/a> color picker script. \u00a0The new Iris color picker is shown off in the Theme Customizer for the Twenty-Twelve theme.<\/p>\n<p><img class=\"aligncenter size-full wp-image-1634\" src=\"http:\/\/rachelbaker.me\/wp-content\/uploads\/2012\/11\/WordPress-theme-customizer-color-picker2.png\" alt=\"\" \/><\/p>\n<p>As soon as I saw Iris, I fell in love. She is user-friendly, colorful and fun. I found that implementing the new color picker is <a title=\"Adding Farbtastic to WordPress Widgets\" href=\"http:\/\/pippinsplugins.com\/adding-the-farbtastic-color-picker-to-your-wordpress-widgets\/\">very similar to Farbtastic<\/a>.<\/p>\n<h3>Iris Color Picker Demo Plugin<\/h3>\n<p>To use the Iris color picker in a plugin requires:<\/p>\n<ol>\n<li>Running a version of WordPress that is 3.5 Beta or higher.<\/li>\n<li>Loading the ‘wp-color-picker’ script and style into your plugin options page.<\/li>\n<li>Adding a text input for your color value to your plugin options page.<\/li>\n<li>Writing a custom jQuery script to call Iris’s wpColorPicker method on your color text input field(s).<\/li>\n<\/ol>\n<p><strong>How does the code look for implementing steps 2-4?<\/strong><br \/>\nI created a demonstration plugin to help answer that. The plugin doesn’t do anything itself, it is only intended as a guide for developers interested in using the new Iris color picker in a WordPress plugin.<\/p>\n<p><a class=\"button\" href=\"https:\/\/github.com\/rachelbaker\/iris-color-picker-demo\">View on Github<\/a><\/p>\n<p><img class=\"aligncenter size-full wp-image-1635\" src=\"http:\/\/rachelbaker.me\/wp-content\/uploads\/2012\/11\/screenshot-iris-color-picker-demo.jpeg\" alt=\"Iris Color Picker Demo Plugin\" \/><\/p>\n",
    "parent": null,
    "link": "http:\/\/rachelbaker.me\/how-to-use-the-new-wordpress-color-picker-in-a-plugin\/",
    "date": "2012-11-27T17:47:36",
    "modified": "2015-04-09T15:24:40",
    "format": "standard",
    "slug": "how-to-use-the-new-wordpress-color-picker-in-a-plugin",
    "guid": "http:\/\/rachelbaker.me\/?p=1631",
    "excerpt": "<p>One of the many new features in WordPress 3.5 is the Iris color picker. \u00a0Iris replaces the, now deprecated, Farbtastic color picker script. \u00a0The new Iris color picker is shown off in the Theme Customizer for the Twenty-Twelve theme. As soon as I saw Iris, I fell in love. She is user-friendly, colorful and fun.<a href=\"http:\/\/rachelbaker.me\/how-to-use-the-new-wordpress-color-picker-in-a-plugin\/\" title=\"Use the New WordPress 3.5 Color Picker in a Plugin\" class=\"more js-control\">…<span>↪<\/span><\/a><\/p>\n",
    "menu_order": 0,
    "comment_status": "open",
    "ping_status": "open",
    "sticky": false,
    "date_tz": "Etc\/GMT-6",
    "date_gmt": "2012-11-27T23:47:36",
    "modified_tz": "Etc\/GMT-6",
    "modified_gmt": "2015-04-09T21:24:40",
    "meta": {
      "links": {
        "self": "http:\/\/rachelbaker.me\/wp-json\/posts\/1631",
        "author": "http:\/\/rachelbaker.me\/wp-json\/users\/1",
        "collection": "http:\/\/rachelbaker.me\/wp-json\/posts",
        "replies": "http:\/\/rachelbaker.me\/wp-json\/posts\/1631\/comments",
        "version-history": "http:\/\/rachelbaker.me\/wp-json\/posts\/1631\/revisions"
      }
    },
    "featured_image": null,
    "terms": {
      "category": [
        {
          "ID": 13,
          "name": "Web Development",
          "slug": "web-development",
          "description": "",
          "taxonomy": "category",
          "parent": null,
          "count": 21,
          "link": "http:\/\/rachelbaker.me\/category\/web-development\/",
          "meta": {
            "links": {
              "collection": "http:\/\/rachelbaker.me\/wp-json\/taxonomies\/category\/terms",
              "self": "http:\/\/rachelbaker.me\/wp-json\/taxonomies\/category\/terms\/13"
            }
          }
        },
        {
          "ID": 15,
          "name": "WordPress",
          "slug": "wordpress-2",
          "description": "",
          "taxonomy": "category",
          "parent": null,
          "count": 19,
          "link": "http:\/\/rachelbaker.me\/category\/wordpress-2\/",
          "meta": {
            "links": {
              "collection": "http:\/\/rachelbaker.me\/wp-json\/taxonomies\/category\/terms",
              "self": "http:\/\/rachelbaker.me\/wp-json\/taxonomies\/category\/terms\/15"
            }
          }
        }
      ]
    }
  }

This example, taken from developer Rachel Baker’s website, shows the content of one of the posts being returned.

Because there’s no front end display being generated, the response time on the API calls is very fast, and the server overhead low, meaning that even lower end WordPress installs will be able to scale this sort of functionality much larger than the traditional browser display. And, because the data is being parsed by wp-query, all of the standard query args can be applied to the output. For example, to filter by category, you simply add the filter call, and specify the category in question:

GET http://yoursite.com/wp-json/posts?filter[category]=some-topic

To return your custom post types, send a type arg with the query:

GET http://yoursite.com/wp-json/posts?type=product

Adding, updating, and deleting all of the supported data objects is supported via the PUT request, which requires authentication:

PUT /posts/<id>

Authentication is achieved by installing the separate Basic Auth plugin, and passing a request to the /oauth1/authorize endpoint, which creates an access token for the requesting application. There are a number of scopes for authorization spelled out in the documentation.

There are some weaknesses to the default functionality, not the least of which is native support for displaying custom fields. Fortunately, there are hooks in place to allow you to shape that output. For example, if you use Advanced Custom Fields, and want to return those fields with your call, the json_prepare_post hook can be used to pregather the fields you’ve created, and send them along as an additional key/value pair in your JSON return:

add_filter('json_prepare_post', 'json_api_encode_acf');

function json_api_encode_acf($post) {
    
    $acf = get_fields($post['ID']);
    
    if (isset($post)) {
      $post['acf'] = $acf;
    }

    return $post;

}

While the possibilities are exciting, it’s not quite ready for prime time just yet. Despite having a stable version in the WordPress plugin repository, development notes on version 2 indicate there will be no backwards compatibility to version 1, and there have been two recent security patches released closing some pretty substantial holes in the API. Additionally, although initially slotted for inclusion with 4.1, it didn’t make that goal, and doesn’t appear to be on the change list for versions 4.3 or 4.4. Anyone working with the development version at Github is met with the following message:

The “develop” branch is undergoing substantial changes and is NOT COMPLETE OR STABLE.Read the in-progress documentation to introduce yourself to endpoints, internal patterns, and implementation details.

That being said, it’s absolutely worthwhile downloading and experimenting with the plugin now, as this represents the next generation of WordPress development. Those familiar with the architecture will have a leg up when it is bundled into core, likely early next year. Once it’s integrated, you can expect to quickly see a bevy of new WordPress admin apps to make it easier to do things like post photos from your phone to your site, but for those creative enough to see WordPress as the object engine it is, this will usher in an era of WordPress powered apps.

How would you use the API? Let us know in the comments below!