本書を手にとっていただき、ありがとうございます。本書は技術書典13にて頒布した同人誌『バックエンドエンジニアによる初めてのJamstack リアルタイム更新スコアボード開発』に加筆修正を加えたものです。株式会社インプレスR&D様のご厚意により、今回商業出版の運びとなりました。
バックエンド開発に長く携わってきましたが、サーバー管理に求められる知識やスキルが高度化し、純粋なプログラミング以外に必要な知識や作業が増えて限界を感じていました。
そうした中で、Jamstackという構成に関心を抱きました。サーバー管理にまつわる諸々を専門の事業者に任せ、アプリケーションのロジックのみに専念するフロントエンド中心の開発手法です。バックエンド・エンジニアとしてあらゆることをサーバーで処理することに注力してきたことから、こうした手法には戸惑いとともに、大きな可能性を感じました。
そこでシンプルなチュートリアル以上の実際に役立つものを自分で設計して作ってみたい、と考えて今回のプロジェクトに挑みました。直感的にできそうでできないことなど苦労した点もありましたので、そうした知見を共有できればと考えました。同様の問題意識を感じている方、あるいは単にJamstackで何か意味のあるものを作ろうとするときに具体的にはどのように行うのかを知りたい方に、特にお役立ていただけると思います。
本書は以下の前提条件を満たす方を対象として書かれています。こうした事柄について細かな説明はありませんので、ご注意ください。
・Githubのアカウント
できあがったコードをGithubとNetlifyで連携させることで、pushしたものを自動的にデプロイできます。
・JavaScriptの経験
・npmなどコマンドラインツールの経験
・SQLの知識
・CSSの知識
・筆者の開発環境(これ以外の環境でも使用できます)
─OS: MacOS Big Sur
─IDE: PhpStorm
本書に記載されている会社名、製品名などは、一般に各社の登録商標または商標、商品名です。会社名、製品名については、本文中では©、®、™マークなどは表示していません。
本書に記載されている内容は、2022年10月時点の内容です。使用しているフレームワークや各種サービスのバージョンが変わったり、インターフェースが変更されたりして記載通りに操作できなかったり、画面が遷移しなかったりする可能性があります。その場合はそれぞれの公式ドキュメントから最新の情報を得て適時調整してください。
本書を用いた開発、製作、運用、試験などにおいて、著者及び出版社は一切の責任を負いません。提供されている情報の活用はご自身の責任において行ってください。
何を最終的な完成物とするか、そのためにどういう思考過程を経て技術選定に至ったかを紹介します。
とあるゲームのプロジェクトで、スコアボードにいろんな参加者のスコアをリアルタイムで変動させたいという要件が発生しました。スコア自体はデータベースに保存するので、スコアを表示するページをPHPか何かで作って、メタタグでリフレッシュさせればどうですか、と提案して怒られました。もっとスマートにリアルタイムでスコアを変動させろとのことです。
そういえば大昔にCometというサーバーからのプッシュ通知で似たようなことを実現したことがあるなあ、などと思いつつ、さすがにもうCometは存在しないか、あってももっと別の方法があるでしょう。
最近かじりだした、Jamstackを使えばできそうだ、と考えていろいろな試行錯誤を繰り返しつつなんとか実現できたので、その記録と将来の自分、さらには同じようなことで困っている誰かのために手順を記すことにしました。
とあるゲームのスコアボードが表示されるページを作成します。その中にはプレーヤー名と、リアルタイムのスコアが表示されています。最終的に目指すのは、そのスコアを保存するデータベースが更新されるたびに、ページ上に表示している該当プレーヤーのスコアも同時に反映される仕組みを作りたいと思います。
また、そうしたスコアを更新するためのAPIとなるプログラムも、サーバーレスの環境を使用して作ってみたいと思います。
フロントエンドの技術としては、Vue.jsを使用することにしました。これも少しかじったことがあるためです。
データ更新をリアルタイムで監視し、通知する必要があります。いろいろな方法がありそうでしたが、今回はSupabaseのサブスクリプションという機能を使用することで、簡単に実現できそうでした。
できあがったプログラムの置き場は、Netlifyをデプロイ先に選ぶことにしました。また実際にゲームは作りませんが、スコアデータを更新するためのプログラムはNetlify Functionsというサーバーレス機能を使用することにしました。
バックエンドの技術でウェブアプリケーションを開発してきた経験から、フロントエンドとはJavaScriptを使ってJQueryみたいなものでページを一部インタラクティブにする小細工、くらいにしか思っていませんでした。しかし今では全く違う進化を遂げてきて、最近のエンジニアはApacheやNginxのインストールなどを自分でしたりはせず、MySQLをセットアップするために./configure、 make、 make installなどのコマンドを叩くのも古きよきやり方になりつつあることに気づきました。そうしたインフラ的なことはIaaSサービスに任せて、ウェブアプリケーションをすばやく開発するのが最近のトレンドのようです。
それで今回の案件は、実際にモダンな構成であるJamstackを本格的に使ってみるのにいいプロジェクトだと思い、自分の知っているやり方ではなく、Jamstackをフルに使用したもので構成しようと考えました。
まず今回の設計では、Vue.jsで構築したフロントエンドのスコアボードを、Netlify上にアップすることになります。それで最初のステップとして、Netlifyのアカウント作成と基本となる操作を行ってみます。
その後、データを格納する箱を用意します。このスコアボードはSupabaseのデータの変更を監視しており、変更があれば自動的に自分の画面を再描画するという仕組みです。それでSupabaseを使用してテーブルを作成し、スコアの入れ物を作りましょう。
しかしその前に、Jamstackとは何かについて少し説明したいと思います。
本書のテーマであるJamstack(ジャムスタック)とは何かを簡単に説明します。それが何なのか、どういう用途に向いているのかを理解しておくと、今後の技術選定に役立つことでしょう。
まずはJamstackを語る前に、ここでいう「スタック」とは何かをはっきりしておきたいと思います。スタックとは、ウェブアプリケーションにおける使用するサービスやアプリケーションの構成のことです。たとえば広く使用されているWordPressは、一般的にはLAMPスタックと呼ばれる構成で稼働しています。それぞれのアルファベットが使用している技術の頭文字です。
・L: Linux(サーバーOS)
・A: Apache(ウェブサーバー)
・M: MySQL(データベース)
・P: PHP(プログラミング言語)
これは当然、構成によって変わります。たとえばウェブサーバーにApacheの代わりにNginxを使用するならAの部分がNに代わり、LNMPスタックとなります。
同様のものとして、MEANスタックというのもあります。
・M: MongoDB(データベース)
・E: Express(バックエンドのフレームワーク)
・A: Angular(フロントエンドのフレームワーク)
・N: Node.js(JavaScript実行環境)
構成の要素が一致していませんね。スタックという言葉に明確な定義や規格が存在しないことがわかりますので、一種のバズワードともいえるかもしれません。しかし、どんな構成で何を使っているかを簡潔に表現できるので、好んで使われているようです。
では、Jamstackとは何でしょうか。元々は「JAMStack」と大文字で表現されていました。JはJavaScript、AはAPI、そしてMはマークアップです。しかし現在ではそれ以外のもの、たとえばヘッドレスCMSなどJamstackに欠かせない要素となっているものもあるため、特定の頭文字を表さない「Jamstack」と表記されるようになりました。
Jamstackは基本的に、プログラミングのロジック以外のところはすべて専門のサービスを使用します。そして特定のプラットフォームに依存しないデータの管理をします。これまで開発者がなし崩し的に担当してきた多くの作業から開放され、結果として開発者は本来のアプリケーション開発に集中することができます。たとえば、以下のようなメリットがあります。
多くのウェブアプリケーションは、表示がもっさりとしていると感じます。これはページを表示しようとする際に、データベースへの問い合わせが複数発生していることに起因することが多いはずです。Jamstackのサイトは基本的には事前にHTMLを生成しておいて、それを表示するため高速です。
インターネット上に露出しているサイトは、何らかのサイバー攻撃の対象になりやすいものです。マイナーな中小企業のサイトなど放っておいても大丈夫、とおっしゃる方もいます。しかし、WordPressなどを使用していると、ボットが自動的に世界中のWordPressサイトへ脆弱性を突いた攻撃を行います。データベースが裏側に稼働していると、中身を抜かれたり書き換えられたりします。
Jamstackのサイトは基本的に単なるHTMLです。仮にハッキングされたとて、被害はたかが知れています。しかもそれらはNetlifyやAWSなど専門のサーバー管理業者が、ホスティングから攻撃防御まで請け負ってくれます。自分でインストールしたウェブサーバーとデータベースを運用することを考えると、その安心感は計り知れません。
たとえば、WordPress内に記事データが蓄積されているとしましょう。そのデータはWordPressという枠組みではテーマを変更したりして、いろいろ展開できるように思えます。しかし、WordPressを辞めて自社のシステムで運用したいと思う場合はどうでしょうか。データの移行がそう簡単ではなさそうなのは、直感的にわかります。
Jamstackでは、そのようなデータはヘッドレスCMSで入力し管理します。ヘッドレスということから、そのデータはどんなプラットフォームにでも自由に使用できます。基本的にJSONなどのフォーマットで取り出すだけなので、それをPDFに保存したり、メールで配信したり、ウェブサイトに掲載したり、自由に展開できる無限の可能性を秘めているのです。
Jamstackでは、自分でウェブサーバーを立ち上げたりしません。これまでは自前でサーバーをセットアップし、それに必要なプログラムを自分でインストールして使ってきました。しかし、サーバーはNetlifyのようなデプロイ環境のプロバイダーにお任せします。すると低価格、もしくは無料で自動スケーリング、クラスター、CDNによるキャッシングと配信を勝手にやってくれるのです。
データベースを安全に管理するためには、ますます専門性が求められるようになりました。しかし、セキュリティーをガチガチに考えてからやろうとすると、開発中は多くの不便を強いられます。データベースのような高度に専門性が必要とされる管理を、片手間で不安を感じながら担当している開発者は少なくないことでしょう。それらから開放されることは心理的負担を大きく軽減します。バックエンドでPHPなどをずっと書いてきた私にとっては、この点がJamstackを選択する大きな理由になっています。
全文検索を実装しようとすると、かなり大変です。でも、JamstackではそれらはAlgoliaのような検索アルゴリズムのプロバイダーにお任せします。
ユーザー認証もDrupalやWordPressのようなフレームワークを使用しないで、自分で実装するのは大変です。でもJamstackではAuth0のような認証だけを専門にやっているサービスを利用します。
Jamstackでは基本的にページをサーバー側で先にレンダリングして用意しておきます。たとえば静的サイトジェネレーターを使用して、サイト内のすべてのページを事前にHTML化しておくことで高速なローディングを実現します。なので、頻繁に動的に表示されるべきデータがあるサイトには不向きです。Jamstackは万能ではなく、WordPressの方がいい選択肢となる場合もあることでしょう。
一方で情報提供のような、そんなに頻繁に更新されないような内容には非常に向いています。キャッシングのメカニズムなどはあるとはいえ、たとえば一般的なCMSでは基本的にページがリクエストされるごとにデータベースへの問い合わせや、そのための各種プログラムが走り出します。それが大きなボトルネックとなり、ローディングが遅いという問題が発生します。
本書では扱いませんが、最近ではページの一部だけ動的に表示するなどの方法もフレームワークに組み込まれるようになってきており、徐々にJamstackが苦手な分野が解消されつつあります。
一般的なJamstackを構成する要素は、たとえば以下のようなものがよく使われています。厳密にいうと定義はもっと細かく分けられるべきですが、何と何が同じカテゴリーかがざっくりとわかるようにグルーピングしてみました。
・フロントエンドのフレームワーク
─Vue.js
─Angular
─React
─Svelte
・デプロイ先
─Netlify
─Vercel
─AWS
・ヘッドレスCMS
─StoryBlok
─Contentful
─microCMS(日本語)
─Newt(日本語)
・静的サイトジェネレーターなど
─Gatsby
─Hugo
─11ty
─Astro
─Next.js(Reactの上位フレームワーク)
─Nuxt.js(Vue.jsの上位フレームワーク)
以上、Jamstackについて基本的な情報をご紹介しました。これらをベースに、様々なサービスを疎結合で結びつける自由度はJamstack構成の魅力のひとつといえます。
本書ではシンプルに実現したい機能を実装するために、フロントエンドのフレームワークとしてのVue.jsとデプロイ先としてのNetlifyを使用します。記事情報のようなものを保存しないので、ヘッドレスCMSではなく、単純なデータベースサービスであるSupabaseを使用します。
EC2のようなサーバーひとつで全部完結する環境に慣れていると、Jamstackのようにあれもこれも別々のパーツを組み合わせることに違和感を持っていました。これらの構成要素のうち、どこから手を付けたらとっつきやすいのがわかりにくいのにも参りました。
たとえばGatsbyがいいらしい、と聞いたとします。しかし、GatsbyはReactの知識に加えてGraphQLという新しいコンセプトにも慣れる必要があり、Jamstack初心者にはとっつきにくいものです。フレームワークや静的サイトジェネレーターの名前で検索しても、その使い方は見つけられても、Jamstackを始めてみたいという人への大きな視点でのロードマップにはなりません。
本書がとっかかりとしてのひとつの例として、お役に立つことを願っています。