{"id":148205,"date":"2015-11-04T11:00:38","date_gmt":"2015-11-04T16:00:38","guid":{"rendered":"http:\/\/premium.wpmudev.org\/blog\/?p=148205"},"modified":"2017-02-28T00:32:45","modified_gmt":"2017-02-28T00:32:45","slug":"using-wordpress-rest-api","status":"publish","type":"post","link":"https:\/\/wpmudev.com\/blog\/using-wordpress-rest-api\/","title":{"rendered":"How to Use the WordPress REST API (and the Companies Already Using it Successfully)"},"content":{"rendered":"<p>There is a lot of buzz around the upcoming REST API for WordPress, and rightly so! After the introduction of custom post types way back in version 2.9, this may be the biggest step toward making WordPress a true application framework.<\/p>\n<p>In a nutshell, the REST API it allows developers to completely de-couple the front-end from the core WordPress package. This will lead to better mobile apps, highly customized themes and \u2013 hopefully \u2013 clever implementations we haven&#8217;t even thought of yet.<\/p>\n<p>In this article, I&#8217;ll show you how to get started with the REST API and some companies already using it successfully.<\/p>\n<p>A quick note: this article is aimed at developers with a solid understanding of PHP and WordPress.<\/p>\n<h3>Getting Started With the WP REST API<\/h3>\n<p>Right now, you&#8217;ll need the <a href=\"http:\/\/v2.wp-api.org\/\" target=\"_blank\">REST API Plugin<\/a> to get started and the latest version of WordPress. You&#8217;ll also need some knowledge of the WordPress HTTP API to make calls.<\/p>\n<p>As our first project for this tutorial, let&#8217;s create a local WordPress installation, which will pull posts from our live site using the REST API. Make sure you have the REST API plugin installed on the live site and create an empty widget plugin on your local site. Here&#8217;s the boilerplate code I used to get started:<\/p>\n<div class=\"gist\" data-gist=\"d6b4ed7ce06c78d1fe65b9fdc2039091\" data-gist-file=\"plugin-boilerplate.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/d6b4ed7ce06c78d1fe65b9fdc2039091.js?file=plugin-boilerplate.php\">Loading gist d6b4ed7ce06c78d1fe65b9fdc2039091<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>This code is contained within a <code>rest-api-test-widget<\/code> folder in the plugins directory, in a file named <code>rest-api-test-widget.php<\/code>. It contains the plugin header, which is used when listing the plugin in the admin and a tiny bit more than the bare minimum for creating a widget.<\/p>\n<p>If you aren&#8217;t familiar with creating widgets fear not, we have an article on <a href=\"https:\/\/wpmudev.com\/blog\/how-to-build-wordpress-widgets-like-a-pro\/\" target=\"_blank\">building WordPress widgets like a pro<\/a>. In this article, we&#8217;ll mostly focus on the <code>widget()<\/code> function, which governs the output of the widget.<\/p>\n<p>We&#8217;ll also be using the WordPress HTTP API to make requests and read responses from the WordPress API. If you&#8217;re new to HTTP, take a look at our handy <a href=\"https:\/\/wpmudev.com\/blog\/wordpress-http-api\/\" target=\"_blank\">guide on using the HTTP API<\/a>.<\/p>\n<h3>Grabbing Some Posts<\/h3>\n<p>Just as with any REST API, we&#8217;ll need a couple of things to make each request. We need to know the following:<\/p>\n<ul>\n<li>The base path of the API<\/li>\n<li>The route used<\/li>\n<li>The endpoint used<\/li>\n<li>Headers required<\/li>\n<li>Parameters<\/li>\n<\/ul>\n<p>The <strong>base path<\/strong> of the API is always <code>\/wp-json\/wp\/v2\/<\/code>. All routes I&#8217;ll describe will be relative to this path. So the full base URL would be <code>http:\/\/mywebsite.com\/wp-json\/wp\/v2\/<\/code>. The route for getting posts is <code>\/posts<\/code> so the full route URL is <code>http:\/\/mywebsite.com\/wp-json\/wp\/v2\/posts\/<\/code>.<\/p>\n<p>Each route can have a number of endpoints which are differentiated by the HTTP method. The route to a single article might be something like <code>\/posts\/325<\/code>. This route has three endpoints:<\/p>\n<ul>\n<li>GET will retrieve the post<\/li>\n<li>PUT will update the post<\/li>\n<li>DELETE will delete the post<\/li>\n<\/ul>\n<p>For our example, we&#8217;ll be using the <code>http:\/\/mywebsite.com\/wp-json\/wp\/v2\/posts\/<\/code> route with the GET endpoint to retrieve posts. Using the HTTP API, this is a simple line of code.<\/p>\n<div class=\"gist\" data-gist=\"ab967409b30cb1116d78f3e337fef05c\" data-gist-file=\"get-posts.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/ab967409b30cb1116d78f3e337fef05c.js?file=get-posts.php\">Loading gist ab967409b30cb1116d78f3e337fef05c<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>In our case, the response is favorable if it is not a <code>WP_Error<\/code> object and if it returns some posts. The data is returned in the body of the response which we can grab using the <code>wp_remote_retrieve_body()<\/code> function. The body will contain a JSON encoded string with post data. Here&#8217;s the full code for displaying them in our widget.<\/p>\n<div class=\"gist\" data-gist=\"e39f7dacb40d1baf7089304a8dc6a9b6\" data-gist-file=\"show-posts.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/e39f7dacb40d1baf7089304a8dc6a9b6.js?file=show-posts.php\">Loading gist e39f7dacb40d1baf7089304a8dc6a9b6<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>This seems like a simplistic example \u2013 and it is \u2013 but the potential it holds is amazing. If you replace the HTTP API functions with cURL or something else, our example is basically WordPress-agnostic. We could be working in Laravel, Joomla or a mobile application. The fact that we&#8217;re displaying posts from WordPress in <em>another<\/em> WordPress system is pure coincidence.<\/p>\n<p>This means that you could create a mobile app for your WooCommerce store which is completely iPhone\/Android native, yet interacts with your WordPress site perfectly, including taking orders, managing shipments and receiving payments. It turns WordPress into an app platform which should make all our websites that much better.<\/p>\n<h3>Doing More With the REST API<\/h3>\n<p>This basic example shows 90% of how you work with the WP API. There are three more things that it is worth looking into briefly:<\/p>\n<ul>\n<li>Caching responses<\/li>\n<li>Authentication<\/li>\n<li>Discovering more to do<\/li>\n<\/ul>\n<h4>Caching Responses<\/h4>\n<p>It doesn&#8217;t do to continuously bother servers with calls when they aren&#8217;t needed. In our example above we&#8217;ve displayed a list of posts which probably won&#8217;t change within seconds. Caching this response for an hour, maybe even a day, would be a good idea.<\/p>\n<p>There are a number of approaches to solve this, including <a href=\"https:\/\/github.com\/Shelob9\/jp-rest-cache\" target=\"_blank\">JP REST API CACHE<\/a> which is a composer library, caching plugins and using native transients. I&#8217;ll show you a quick transients example here.<\/p>\n<p>The idea of a transient is that it stores data with an expiration date. By default it will go into the database but some setups allow storage in memory which makes it even faster. When we retrieve the posts we want to put them in a transient and set the expiration to an hour. Until the expiration time arrives the posts are retrieved from our own database. After expiration they are retrieved from the external site once again and put into the transient.<\/p>\n<p>Here&#8217;s how I would modify the widget function (creating an additional function in the process).<\/p>\n<div class=\"gist\" data-gist=\"be9f75aecac1a60c36d6cd825436ccd9\" data-gist-file=\"cached-posts.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/be9f75aecac1a60c36d6cd825436ccd9.js?file=cached-posts.php\">Loading gist be9f75aecac1a60c36d6cd825436ccd9<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<h4>Authentication<\/h4>\n<p>The method above should work without authentication but you should <strong>always<\/strong> authenticate yourself. Take a look at the <a href=\"http:\/\/v2.wp-api.org\/guide\/authentication\/\" target=\"_blank\">Authentication<\/a> section in the documentation for more info. When working with external requests like this you have two options: basic authentication and OAuth.<\/p>\n<p><strong>Basic authentication<\/strong> is the simplest but should <strong>never<\/strong> be used in production as it is quite unsafe, it requires you to send your actual username and password with each request. It is a good method for testing though so I&#8217;ll show you how to get it up and running.<\/p>\n<p><strong>Basic Authentication<\/strong><\/p>\n<p>To enable basic authentication, you need to install <a href=\"https:\/\/github.com\/WP-API\/Basic-Auth\" target=\"_blank\">a plugin<\/a> on the target site. Once this has been activated you&#8217;ll be able to make authenticated calls.<\/p>\n<p>To get started you need to set an authorization header with the value <code>Basic &lt;Base64 encoded username:password&gt;<\/code>. Assuming your username is <strong>mrawesome<\/strong> and your password is <strong>awesomepass<\/strong> you could create this header and authenticate a call like so:<\/p>\n<div class=\"gist\" data-gist=\"5848e66f6d0e55d7d8e851bff637d800\" data-gist-file=\"delete-post.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/5848e66f6d0e55d7d8e851bff637d800.js?file=delete-post.php\">Loading gist 5848e66f6d0e55d7d8e851bff637d800<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>Take care, if you use your own website URL and are properly authenticated this will delete the post with the ID of 1183! As you can see, manipulating data is extremely simple with the API, it really is a joy to work with.<\/p>\n<p><strong>OAuth Authentication<\/strong><\/p>\n<p>This method of authentication also requires you to install <a href=\"https:\/\/github.com\/WP-API\/OAuth1\" target=\"_blank\">a plugin<\/a>. Once the API is merged into core this plugin will be included so you won&#8217;t need to worry about multiple separate plugins. Unfortunately at the moment the documentation for OAuth is a mess so I won&#8217;t be able to show you how to get this done right now.<\/p>\n<p>It involves installing using <a href=\"http:\/\/wp-cli.org\/\" target=\"_blank\">WP-CLI<\/a> a command line interface for WordPress, installing a community extension for it, the <a href=\"https:\/\/github.com\/WP-API\/client-cli\" target=\"_blank\">WP Client CLI<\/a> and using those two together. This would not really pose a problem, but a command listed isn&#8217;t available and it is making our lives harder than it needs to be.<\/p>\n<p>Once easy-to-use instructions are available I&#8217;ll report back on how to do this. For now, we can stick to testing the waters with the basic authentication.<\/p>\n<h4>Discovering More To Do<\/h4>\n<p>I highly recommend reading the <a href=\"http:\/\/v2.wp-api.org\/guide\/discovery\/\" target=\"_blank\">Discovery<\/a> page of the documentation and just browsing around in general. You&#8217;ll find all the methods that allow you to interact with users, post types, media, meta data and everything else you might need.<\/p>\n<p>A part of learning any API is familiarizing yourself with all the options and the WordPress API is no exception. You&#8217;ll find some quirks like not being able to delete users and other minor issues, but keep in mind that this is still work in progress and is shaping up beautifully.<\/p>\n<h3>Companies Using The REST API Right Now<\/h3>\n<p>Even as the REST API is emerging from its infancy, many companies are already using it.<\/p>\n<p>Here&#8217;s a list of just some of them testing the waters:<\/p>\n<ul>\n<li><a href=\"http:\/\/eventespresso.com\/2015\/07\/event-espresso-4-rest-api-add-on-available\/\" target=\"_blank\">Event Espresso<\/a>, a popular event management plugin is using it to provide access to its data<\/li>\n<li><a href=\"https:\/\/make.wordpress.org\/core\/2015\/07\/23\/rest-api-whos-using-this-thing\/#comment-26357\" target=\"_blank\">Human Made<\/a> is using it to create client sites when the client wants something more flexible in the front-end.<\/li>\n<li>A premium plugin called <a href=\"https:\/\/edituswp.com\/\" target=\"_blank\">Editus<\/a> is using it to power it&#8217;s front-end editing capabilities<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/wp-search-live\/\" target=\"_blank\">WP Search Live<\/a> &#8211; a free plugin &#8211; uses it to power its search functionality<\/li>\n<li>JoinIn is using it to power an embeddable JS widget<\/li>\n<li><a href=\"https:\/\/make.wordpress.org\/core\/2015\/07\/23\/rest-api-whos-using-this-thing\/#comment-26386\" target=\"_blank\">Modern Tribe<\/a> is using it to power both Handlebars and full page React templates in their themes<\/li>\n<li><a href=\"https:\/\/simmerwp.com\/\" target=\"_blank\">Simmer<\/a> &#8211; a recipe publishing tool &#8211; is using it to build their own developer APIs and to help others make cookbooks into mobile apps that they can easily sell.<\/li>\n<li>According to the <a href=\"https:\/\/make.wordpress.org\/core\/2015\/07\/23\/rest-api-whos-using-this-thing\/\" target=\"_blank\">Who&#8217;s using this thing?<\/a> post on Make WordPress a lot of people are using the API to create mobile apps for their websites.<\/li>\n<\/ul>\n<h2>Where Do You Fit In?<\/h2>\n<p>Are you using the WP REST API? We&#8217;d love to hear how you are using it, or plan to use it.<\/p>\n<p>What do you think about the opportunities it provides? Do you see it as the way forward for the WordPress community or is it just a passing fad?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There is a lot of buzz around the upcoming REST API for WordPress, and rightly so! After the introduction of custom post types way back in version 2.9, this may be the biggest step toward making WordPress a true application framework. Here&#8217;s how you can get started using the API.<\/p>\n","protected":false},"author":344049,"featured_media":162934,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"blog_reading_time":"","wds_primary_category":0,"wds_primary_tutorials_categories":0,"footnotes":""},"categories":[557,263],"tags":[10301],"tutorials_categories":[],"class_list":["post-148205","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development","category-tutorials","tag-wp-rest-api"],"_links":{"self":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/148205","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/users\/344049"}],"replies":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/comments?post=148205"}],"version-history":[{"count":8,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/148205\/revisions"}],"predecessor-version":[{"id":209667,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/148205\/revisions\/209667"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media\/162934"}],"wp:attachment":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media?parent=148205"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/categories?post=148205"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tags?post=148205"},{"taxonomy":"tutorials_categories","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tutorials_categories?post=148205"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}