Over the last few years I've become interested in architectures for serving content that consist in a separate backend API and a standalone frontend application which consumes and presents data. Headless CMSs have become quite popular amongst web developers and many of the existing big players in the content management industry are following the trend. While playing around with projects like Strapi, Cockpit and Contentful, I remembered about ProcessWire.
ProcessWire is a free powerful PHP content management system. With a simple jQuery-like API, a solid structure and an impressive flexibility, it's a really good choice for any kind of website.
We used it for one of our clients in my previous company and it was fun to work with. On the administration side, ProcessWire provides a straightforward interface which resembles any other admin panel content folks are used to (our client was happy to be working with something as much user-friendly as WordPress).
I looked into the recent changes in the ProcessWire world and found out that the CMS can be used as decoupled backend, its API exposed through REST calls. Even more exciting, a guy developed a module to made the content accessible via GraphQL queries 🤤. So I gave it a try.
If you don't have ProcessWire, you can easily install it locally. Here are some official tutorials for doing that.
The next step would be to install the GraphQL module. Once the module is installed and activated, you'd have to create a new template which is gonna be used by the page exposing your public API. Just create one called graphql
or api
and then create a new page with the same name. This page can be set as 'Hidden' so it will be exclude from lists and searches. Then, in your ProcessWire folder, navigate to /site/templates/
and create a new file with the same name as the template you've just created, like graphql.php
. All the public API page has to do is execute any GraphQL query coming from your decoupled frontend. The content of this file is simply:
<?php namespace ProcessWire;
echo $modules->get('ProcessGraphQL')->executeGraphQL();
By default, the GraphQL module doesn't expose much publicly, letting the developer choose what to allow to be queried. In the ProcessWire admin panel, go to Modules > Site > ProcessGraphQL. You'll see a bunch of options for exposing templates, fields and other things to the public (you can read more details about the settings on the module's github page). In my example, I had a basic_page
template and each page has a title and some content. All I had to do here was to select basic_page
from the Legal Templates section and content
from Legal Fields.
The module offers a GraphiQL interface so you can test your queries before implementing them into the frontend application. With that, I can do something like:
{
basic_page {
list {
name
content
}
}
}
and what I get in return is a list of pages using that template, with the values of name
and content
populated.
In your frontend application, you can then use that query and fetch data from ProcessWire. Make sure Cross-Origin Resource Sharing is enabled on the CMS API side in case your backend and frontend are accessed on separate domains, otherwise the latter won't be able to access the data. In Apache for example, provided you have a virtual host in place, you would set the necessary headers this way:
<VirtualHost *:80>
...
Header set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, PUT, GET, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type"
</VirtualHost>
Here's how a dead simple application could work:
Resources: