When we initially created Webiny we started by building every app as a separate module with its own backend system. This included the Page Builder, Form Builder and File Manager. Eventually we created our own Headless CMS.
Over time, we tried using Headless CMS as a backend for our new applications, like the Advanced Publishing Workflow and the Advanced Content Organization.
This had proven to be very beneficial as it mean we drastically reduced the backend code, potential for bugs, and lowered the effort required to maintain those applications. One other very important benefit we also gained with this approach was that the API was way more powerful and it was easy to extend it, which was important to users that wanted to add and store additional attributes and build new features on top of those existing applications.
Our goal is to now move all existing applications to use the Headless CMS to use it as the backend. We have already refactored and moved the File Manager app, and the next one we want to tackle is the Form Builder.
The high-level approach is as follows:
create programmatic HCMS content models (File Manager or ACO)
create an implementation of StorageOperations (File Manager or ACO)
context.cms
) to call CRUD on the new content model.create a custom app GraphQL schema
your CRUD files will mostly remain the same, because your storage operations implementation will follow the same interface, and it’s the storage class’s responsibility to transform the data into the shape suitable for the actual headless CMS storage layer. You’ll find all the necessary examples within the File Manager code referenced above.
where
input to fit the underlying HCMS querying input.existing Jest tests will also be 100% applicable, so you can use them immediately in your development process. You can also keep the original configuration of the handler, and just add a conditional override of the storage operations during the context setup, to be able to toggle the 2 storage ops on/off as you see fit. See here how I take into account the existing storageOps that are injected into the plugin factory, but then override the storageOperations.files
with a new implementation.
Imagine you’re a 3rd party developer, and you’re using Headless CMS as your data store, via GraphQL API. Think of how you would implement the content model for the Form, and Form Submissions. Then simply transfer that into the code models.
Revisions in the Form Builder map nicely onto revisions in the Headless CMS. There’s one problem though: Form Builder is the only app that allows multiple revisions to be published at the same time. The trick here will be to have a published: Boolean
field on your Form content model and update that field accordingly. Then you can query published revisions using that field. Publishing of HCMS records will never really be happening; you will always be using draft
revisions in the Headless CMS itself.