September 2nd, 2020
Okay firstly, a disclaimer: This website is currently getting its blog posts from Contentful. I'm also using Contentful for managing partner configurations in an enterprise solution. I use it all the time and I'm even writing this blog post within the Contentful UI.
So, you would think that the best possible CMS solution for me would be Contentful? Well, while I do think Contentful is really good, I think that specifically for Engineers, the best possible solution is Strapi.
In fact, time and time again I find myself absolutely astonished by how great a tool it is for engineers, for one main reason:
By default, Strapi abstracts all of the low-level confusion away from you, but unlike most enterprise CMS solutions, Strapi lets you get at that bare metal. If I wanted to never really touch the CMS code, I can still use Strapi. If I want to control every little thing to do with Strapi, I can do that too. The joy really comes from how you can start with a really simple solution and add any customisation that you like.
So, out of the box what do you get?
Well, loads. The most important bits are that you can have full CRUD functionality and user-access management without touching the code. It will even give you a user-interface to change these things. That's pretty cool.
This makes it as good as any other CMS, except you have the nuisance of setting it up on something like AWS. So far, so... fine.
However, before long I realised that I only wanted users to be able to make requests for data that they had created, and this didn't exist immediately. With only a few minutes of researching, I found out how to make a custom controller to do this.
Next, I found that I wanted to generate custom profiles with each user generated. Another thing I was able to do. Custom policies and services? No problem either.
Full support for bootstrap scripts come out of the box so I was able to generate mock data, user role access, and even an admin user. CRON jobs are also supported out of the box. Adding robust GraphQL support is as simple as a single terminal command.
Do you have a particular database that you want to use? No worries. Strapi has you covered. There are several databases to choose from, like SQLite, MySQL, MongoDB, and Postgres to name a few. There are also extra plugins to connect to database variations, like DynamoDB, if you look hard enough. The amount of support there is pretty thin, but then, these are often edge case situations anyway. If you want to have many databases for different models, that's supported too!
Dockerising Strapi is also super easy too. There are tips and tutorials on doing so. In fact, there is tutorials for just about everything. I don't consider myself to be an AWS expert, but there is more than enough information here to set a robust solution up on AWS. It's great. For everything that doesn't have a tutorial, there is a huge dedicated community.
The most important thing here is that generating the structure of your data contract is really powerful. I can structure my data in just about any way I want to. It is in fact so good that, if I felt like doing something insane, I could generate an app, and then generate an api afterward, without even having to go near too much code. If I want to have defaults on all of my empty data, I can set that. I can choose whats required. I can choose what has to be unique. I can choose what the expect data type is. I can create dynamic polymorphic relationships between parents and children, and even choose the type of relationship structure. Basically, I can control everything extremely easily, and then build on it in code as I see fit. That is what makes it better than any other solution right now.
Okay so it's perfect? Well, not quite.
Don't get me wrong - I do think it's the best headless CMS solution for engineers. There are a couple of small issues I've come across, though.
Okay one more disclaimer: These guys are moving so fast in improving things that if you read this a year or two later, this may no longer be an issue.
Strapi, by default, doesn't support HTTP-only cookies for things like JWT Tokens. You can add in support yourself, but I did this and I found it kind of a nuisance. Not a deal breaker, but XSS is the absolute worst and while HTTP-only cookies aren't a fool proof solution, they certainly make things harder.
Strapi also doesn't have out-of-the-box monorepo support. I hear this is coming but I don't know of any dates. I think something like Strapi would be really propelled with monorepo support, because you could have the component level model and data-contract level model share the same source of truth then. I think would be a total game changer that would eliminate a ton of potential bugs in an enterprise solution.
Finally (and this is a nitpick for something super specific that I encountered), I found that when using a REST approach with dynamic zones, it is currently impossible to get a full tree response when there are many levels of relations. When you know what the child in the relationship is going to be, you can drill through as many layers deep in data as you like, but when you have a polymorphic relationship and you're not sure of the exact child structure, you simply can't do that. With GraphQL, you can do this by specifying every possible potential child, but that also ends up with you creating a pretty gigantic request body.
All of these issues are not a big deal and are infinitely outweighed by the positives. I feel as if there is a strong likelihood that these issues will be fixed, with the exception of the last issue because it is kind of an edge case.
So why don't I use Strapi for the content on this website?
For the particular use-case of having a blog on a statically generated website, I don't believe that swapping over is necessary at this time, but if I ever decide that I'd like to add a comments system or voting system, it would be a no brainer for me to use Strapi. The only negative for something like Strapi is the initial knowledge barrier, but as an engineer, it was an absolute joy to learn.
If you need a headless CMS solution for a greenfield project, this is the best solution in my opinion.