Seasonal Color Palettes and Style Tips to Refresh Your Website for the Holidays
One of the areas where WordPress shines is content management. This is also corroborated by the fact that it is the world's leading Content Management System, or CMS, by numbers.
The most popular way of displaying the content hosted by WordPress is through a frontend, like through blog posts and pages. That is wonderful for human visitors but there are other ways of consuming that content -- for example, web APIs.
In this article, we'll explore how we can leverage WordPress in order to power a central API for projects like phone apps, browser extensions, or the frontends of other WordPress sites!
All the steps described in this article were made in WordPress Playground. If you want to see the end result and maybe sometimes skip ahead as we go, download this ZIP file, and perform these steps:
API stands for Application Programming Interface and it's a way for software applications to communicate with each other in a standardized fashion. A web API is simply one that is accessed through "the internet" -- for example, by entering a certain URL in your web browser.
There are multiple types of web APIs, and one common way to group them is the protocol they use. In this article, we'll be implementing two APIs, one based on the REST protocol, and another based on the GraphQL protocol. Other protocols you might have heard of include SOAP, RPC, or gRPC.
WordPress actually includes a built-in REST API which powers the Gutenberg Block Editor. As of October 2024, the popular WPGraphQL plugin has become a canonical plugin paving the road for an official GraphQL API as well.
By the end of this article, we'll have built a WordPress site that allows users to login in order to add/update/delete data entries which will be queryable both via REST routes and a GraphQL endpoint.
The data entries will collectively represent a company's organizational chart -- things like employees, teams, and offices. While a little bland, the concepts can be applied to absolutely anything else.
While an optional step, it makes a lot of sense to do this if your site won't be serving any content via pages but exclusively through APIs.
Once you have a hosted WordPress website, you can start by installing a minimalist WordPress theme like Blank Canvas and deleting every single demo post and page on your site. Continue by using the site editor to include information on the homepage for visitors who find it unintentionally.
For example, add your business' name and logo, and tell them that they probably landed there in error. You can also include a button linking to the admin area for maintainers of the content. Something along the lines of:
One way to prevent your site from being found in search engine results is by checking the Discourage search engines from indexing this site in your site's settings.
If you would rather fully lock down the frontend and not even have the homepage described above, you can add the following code snippet either to a plugin like Code Snippets or to your child theme's functions.php file:
Now it's time to focus on the website's admin area and the data modeling part of this tutorial. The most straightforward way of compartmentalizing your data is by using WordPress' built-in functionality of custom post types and custom taxonomies.
While there are many ways to do this, for the purposes of this tutorial, we'll organize our data like this:
In order to create these custom data types, you can either add custom code to your site, or use a plugin (like in this video). A very popular plugin for creating custom post types and taxonomies using the admin interface is Custom Post Type UI - and that is what we'll be using in this tutorial.
Here is the JSON configuration for importing the data into your installation:
At this point, your WordPress admin interface might look something like this:
The Gutenberg block editor is functional, adaptable, and easy to use, and you should be using it to edit your traditional WordPress posts and pages. However, when it comes to CPTs without a frontend, there might not be any content to warrant the use of a performant editor like Gutenberg.
If you are positive that all of the information you need is not HTML-based, then it might make sense to disable Gutenberg for these CPTs and default back to the classic post editor that was the standard before WordPress 5.0.
The simplest way to disable Gutenberg support for a CPT is to set the argument to when registering it (as we've done above).
Alternatively, if you want to keep the built-in REST routes that WordPress provides for every CPT, you can add this code to your child theme:
Now that we have our basic data types in place, we need to start populating them with entries. Before we do that, we need to ensure that we can record all the necessary data on each entry, and for that we will need to build custom fields.
The easiest way to add custom fields to your custom post types is to register them with support. When you then edit a post, it will include a metabox like this:
While this type of "key-value" interface can be enough, you might want to build a more user-friendly interface with fields like checkboxes, dropdowns, media selectors, and so on.
A popular way to add those types of custom fields is the Meta Box plugin, which, as mentioned above, is what we'll be using in this tutorial. Using their online custom fields generator, we got the PHP code needed to register the fields we wanted and then added them to Code Snippets.
Using a fake data generator, we populated the custom post types with a bit of seed data:
While we won't explore any further UI customization options in this tutorial, we wanted to note that it's possible to use various WordPress filters to tweak things like:
Before we start looking into making the data available via API, it's time to think about who should have access to it.
The custom post types and taxonomies mentioned above were registered in such a way that any logged-in user with the ability to edit regular WordPress blog posts will also have the ability to edit these. However, it's possible to make that much more granular.
You can create custom user roles with custom capabilities in order to ensure that the UI is as clean-as-possible in order to promote focused-work for the users doing the data maintenance. This is particularly important if you anticipate a very high number of entries, especially on an ongoing basis.
While it is possible to control this entirely with custom code, a way to maintain a simpler overview of access management is provided by Access Policies implemented by the Advanced Access Manager plugin.
For example, you can create a separate access policy for each CPT you create. Then you may assign the policy either to a role or to individual users in order to maintain full control over who may add new Employee entries or even just edit existing ones. Deleting entries can be a capability reserved only for administrators.
Notice how the lack of most menu items makes it easier to focus solely on the data-entry aspect. The policies can be made more granular, for example, to also restrict who may delete an entry or create new ones.
While WordPress will automatically create REST routes for every CPT as long as it is registered with the argument set to , you can also create your own custom rest routes that are better suited for serving the CPT content in a way that makes more sense to your use-case.
The easiest and most standard way to achieve this is by extending one of the REST API controller classes. For maximum control over the output, you may want to extend the base WP_REST_Controller class itself.
You can choose to have your routes publicly accessible if the argument is set to the function or you can choose to lock down calls using any permission scheme you want.
The recommended way of locking down access is behind a capability check, i.e. a call to . You can use the AAM Access Policies mentioned above to grant or withdraw permission from individual roles or users, and you can use WordPress' application passwords to authenticate API requests.
Hint: even if you decide that (read) requests should/can be publicly available, we still recommend that any // // (create, update, delete) requests always be guarded by a check.
Here is a REST controller that we added to Code Snippets in order to be able to list the employees on the site and fetch them by ID:
Testing your REST routes
Your custom REST routes will be available under . For example, the path for retrieving the list of employees could look like this:
Hint: the query added there will be parsed by WordPress and made available in the controller; you can then choose to either ignore it or filter the results by it - anything you want!
The easiest way to test your endpoints, especially if they will require an application password to access, is to use a tool like Postman which lets you test APIs in a very user-friendly manner. Publicly available requests can also be tested by simply visiting the URL endpoint in your browser!
Now that we are able to fetch the data via REST routes, let's explore how we might be able to fetch it using GraphQL as well.
If you're unfamiliar with GraphQL, what you need to know is that it's actually a querying language just like SQL but for APIs. You can read more about it on the official website over at https://graphql.org/.
The simplest way to add GraphQL support to our site is by installing the newly-canonical plugin WPGraphQL. It also has a documentation page where you can learn more about what it provides out-of-the-box, and also examples of how to handle much more complex scenarios.
If you've been paying attention to the JSON configuration of the custom post types shared above, you might've already noticed a key named set to (true/active). That is all we need in order to allow the custom post types we added to be queries using GraphQL.
Here is an example of a GraphQL query that can be used to list which you can test in the built-in bundled with the plugin:
If this sounds like something you want to build for your own business, you can work on it on your own computer using Studio by WordPress.com. You can even share your work with colleagues (for free!) using a demo site, and when you're ready, any WordPress.com Business plan or higher will be able to host and manage your site.