病みつきエンジニアブログ

機械学習、Python、Scala、JavaScript、などなど

サーバーレスな Headless CMS を自作して始める Jamstack

この記事は Jamstack Advent Calendar 2020 の 23 日目の記事です。

Jamstack なサイトのアーキテクチャ

Jamstack の厳密な定義などは一旦置いといて、今回は、次のような構成のサイトについて考えます。あまりわかりやすい図ではないかと思うのですが、上段は非同期アクセス、下段はエンドユーザー(閲覧者)からのリアルタイムアクセスです。

f:id:yamitzky:20201222190053p:plain
Jamstack構成図

この構成はざっくりいうと、

  • データは「Headless CMS」と呼ばれる CMS で管理されており、エンドユーザーには見えない
  • エンドユーザーは静的な HTML のみを閲覧する *1
  • なんらかの方法で、「静的な HTML」は非同期に動的更新される (Webhook や Incremental Static Regeneration など)

といった特徴があります。DjangoRails などで作る「動的 HTML 返すサイト」とはちょっと異なります。

このうち、下2つの配信・更新部は Vercel や Netlify などの SaaS を使うことも一般的ですが、Firebase や Amplify のようなサーバーレスなソリューションを使えばかなり安価な従量課金&高いスケーラビリティを実現できます。しかし一方で、「Headless CMS」に関しては、

  • SaaS の場合、月額数百円/人/月の価格設定
  • OSS を自前ホストする場合、MySQL などのデータベース管理が必要
  • 海外製だとほぼ日本語対応されていなかったり、GitHub 前提だとエンジニアではない人に使いづらい

と、 サーバーレス的な課金体系、マネジメントコストで実現できる、使いやすいソリューションが存在しない のが現状です。

Headless CMS の役割

Headless CMS の主要機能は、主に、次のものに分解されます。特に、上の2つがコア機能です。

  • 記事を書いたり編集できる、CMSGUI 機能
  • 記事データなどのデータベースの機能
  • 編集権限などユーザー管理
  • Webhook による更新通知
  • DB を API を通じてアクセスできる機能

この役割は、Firebase などを使えば、ほぼ代替できます*2

  • データベース → Firestore などの BaaS
  • ユーザー管理 → Firebase Authentication などの認証プロバイダ
  • Webhook → GitHub Actions など。ISR であれば不要。
  • API アクセス → Firestore のような BaaS を使えば不要、または、Cloud Functions などで薄くラッピングする。

CMS のアクセス数は一般的に少ないので、月額のインフラコストはほぼゼロです。また、SaaS ではないのでデータのポータビリティも高いです。

残る開発しないといけない部分は CMSGUI 部のみ です。既存の SaaS/OSS の Headless CMS を使わないことによって、GUI の実装に余分な時間がかかることにはなるのですが、 ユースケースに合わせて使いやすい CMS を作るコスト と割り切ることもできるのではないでしょうか。

Headless CMS を自作したアーキテクチャ

業務委託(個人事業)で運営しているホテルのウェブサイトでは、次のような Jamstack の構成にしています。

f:id:yamitzky:20201222191330p:plain

ホテルのサイトにおいては、「動的なコンテンツ」はいわゆる「記事」ではなく、飲食メニュー等になってきます。Headless CMS のガワだけを自作したことによって、これらを使いやすい UI で管理できるようになりました。また、予約管理も Firestore をデータベースとして、同じ CMS 内で予約管理できるようになっています。もちろん、これらの月額固定コストはかなり安価です。

また、JX のプロジェクトでは都構想特設サイトを類似構成で実現し、質問受付システムも Headless CMS 上で対応できるようになりました。これらの「管理」に関してはかなり工数を抑えて実装できています。

tech.jxpress.net

OSS 化してみた

「自作 Headless CMS」に関しては OSS 化をしました*3。Firestore をインフラに使っていて、もちろん日本語対応しています。

github.com

*1:厳密には 、Jamstack では API=動的なものへのアクセスがあります

*2:僕はやったことないですが Amplify でもいけると思います

*3:厳密には OSS 版とホテルの CMS はコードベースが別もので、JX の業務では OSS 版を使っています。知識としての横展開はありますが、成果物としては完全に切り分けています