Exploring Hasura as a Headless CMS
Hasura is a GraphQL API platform which can be used by content writers and developers with the right tooling to build secure content heavy apps for multiple platforms.
- Headless CMS: Quick Intro
- Frontend Tooling
- Extensible via Integrations
- Secure APIs
- Open Source & Self Hosted
Headless CMS is becoming popular among teams with content writers and developers because of the flexibility and the power it gives to both.
In a headless CMS, the front-end system is not coupled with the backend and the developers can build rich experiences with any framework and any platform (web, mobile, IoT etc) of choice. The backend is API driven with structured data. Traditionally you will get a WYSIWYG / HTML editors which is coupled with the database and the CMS is used to edit and preview content live.
Technically the headless CMS is just a data store with a delivery layer.
Hasura would be the content delivery layer via GraphQL, backed by Postgres.
With this architecture, a single GraphQL API gives structured data making it easy to build customised frontends specific to each platform (web, mobile, AR, VR).
Hasura comes with a basic built-in CMS, the Hasura Console. It lets you manage data in Postgres. All tables in postgres schemas which are tracked by GraphQL Engine can be managed using this console. It is primitive and directly mapped to database fields. Here's how a simple data insertion looks like.
It is designed to handle basic data types. In case rich content types including media like images that writers use, then this may not suffice. In this post, we will look at various options that can be used by writers and developers independently for building a CMS with Hasura for advanced workflows.
Developers can choose to build rich content types over Hasura GraphQL APIs as a foundation for their custom CMS. Let's look at the existing frontend tooling available which enables easy customisation.
react-admin is a frontend framework for building admin apps in React. It adapts to any backend via a Data Provider model where the APIs are written to match the format that react-admin is expecting. It comes with rich text editor, custom fields, custom layout and a bunch of built-in components to build an admin panel.
Hasura as a data provider supports react-admin through this package ra-data-hasura which lets you build custom interfaces mapped to fields in postgres.
This is perfect for react developers who wants to build their customised dashboard. Here's an example app of the integration between Hasura and react-admin.
Content authors interested in modifying content via text editor of choice in Markdown, can use static site generators like Gatsby which can source data from Markdown.
This architecture allows for maintaining primary content (eg: blog) via Markdown while associated data (like comments) can come in from Hasura GraphQL via a unique identifier like id or slug. Here is an example of such a use case.
Gatsby.js, a react framework to build web apps, sources data from different data sources. Markdown is one of them.
The idea here is to maintain content in markdown, source it in Gatsby and merge with data from Hasura GraphQL to build the app. When gatsby builds run, we apply an upsert mutation to sync markdown content with the appropriate database fields.
Here's a sample app demonstrating how this can be done with Gatsby + Hasura. This hooks into
gatsby-node.js createPages method to query for markdown content and uses ApolloClient to make a mutation via GraphQL. You can choose to sync raw markdown body optionally along with the unique identifier like slug.
Enter TinaCMS - an editing toolkit for frontend frameworks. This will hook into existing static site generators like Gatsby/Next/Gridsome by providing a layer on top of them (via sidebar UI) and manipulating the content source in realtime.
You can hook up tina-cms plugin to Gatsby for realtime markdown preview.
Currently works with Gatsby and Next with integrations with other frameworks coming soon.
Hasura GraphQL can be extended with external APIs opening up integrations with services which provide a CMS layer.
Remote Joins in Hasura extend the concept of joining data across tables in postgres, to being able to join data across tables and remote data sources. Once you create relationships between types from your database and types created from APIs, you can then “join” them by running GraphQL queries.
This lets a developer to integrate external CMS specific solutions like Contentful so that the content authoring team can independently work on adding rich media sources while developers can leverage Remote Joins to establish relationships between Contentful and Hasura APIs.
Here's how you add Contentful APIs to Hasura via Remote Joins. There's also an example with Gatsby + Contentful to build a music playlist app where the media rich content like images/videos come from Contentful, letting authors manage it easily and the primary content comes from Hasura GraphQL sourced into Gatsby.
There's also a Wordpress plugin called wp-graphql which can be added to Hasura as a remote schema and you can now start managing content through Wordpress while it is joined with primary data in Hasura via Remote Joins.
Headless CMS should not only be API first but also secure. In this section we will see how Hasura helps you configure auth to expose APIs securely to the right stakeholders.
The example that i mentioned above with Gatsby also comes with Auth0 integration. Hasura comes with support for Auth through JWT or webhook modes. Developers can integrate any authentication provider into Hasura with protected routes for content authors managing admin dashboards. Read more about configuring Auth here.
Restricting access to content based on roles is a critical feature for an Headless CMS. Hasura supports role based access control where you can define permission rules for each role. For example, the content authors from marketing team probably doesn't need access to read/write other sensitive backend fields.
All of this can be configured quickly with the console UI abstracting away the complexity for both developers and authors.
If you are exposing the APIs to a team of content writers, you can restrict which queries are allowed to be sent by the client by defining Allow Lists so that Hasura executes only those. This is highly recommended in production instances of Hasura.
On top of role based access control, these are the only queries which will work on the API.
Another key criteria for a Headless CMS is also to see if there's an option to self host with local dev environments for testing. Ideally you would like to own your data instead of hosting it on a cloud provider.
Hasura is open-source, can be self-hosted anywhere and can connect to postgres instance that you can host and control. It comes in a tiny docker image (~30MB) that can be run locally or in the cloud. Here are some of the deployment guides.
The easiest way to get started with Hasura is to deploy it on Heroku.
This gives you an Hasura instance connected to Postgres in under a minute. It's an easy way to play around with the APIs.
When you are using a Headless CMS in general (not just Hasura), you won’t be able to preview content updates instantly on different mediums as you do with traditional CMS.
The workaround here for a web app is to update data -> build on change -> trigger serverless functions to rebuild. A typical example is to host the app on Netlify and trigger Netlify functions to achieve the same. For other platforms, it should work fine if the APIs are used directly to source content.
There's also Gatsby Preview, which gives instant feedback on the content changed by re-building on demand in a staging like setup.
The react-admin data provider mentioned above currently doesn't support Remote Joins.
Headless CMS as a solution is growing among businesses where content teams would like to make changes quickly via an usable interface and developers would like to work with tools and frameworks of their choice.
Hasura GraphQL is an API first solution which can be leveraged with external tooling and APIs to empower content teams. Developers can rely on Hasura GraphQL for efficient querying, type system, a schema with granular access control rules and freedom to work with their favourite frameworks.