https://www.netlify.com/pdf/oreilly-modern-web-development-on-the-jamstack.pdf
Netlify社が2019年に公開した本?PDFです。
せっかくJamstackの会社に入ったので、読んでおかないといけない気がして。
あとJamstackは人によって解釈が違ったりするとし、Jamstackの真髄について知っておきたいですよね?と思い。
ただこれなんと127ページもあるんですよね〜。
全編もちろん英語なので、読むのも中々に大変ですよね〜。
てなわけで、ざっくり訳してまとめまておきました。(それでも長いけど)
はじめに
- ここ最近のWebの進化はすさまじい
- ブラウザもJavaScriptもパワフルになった
- その分ユーザーの要求も増える
- そこで紹介したいのがJAMstack(今はJamstack表記)
- より高速でスケールでき、負荷耐性もあって安全
- モノリシックなシステムに疲弊したことあるよね
- Jamstackの意義がわかるはず
- 開発者だけでなく、ユーザーにもメリットがある
- いわゆるサーバーはいらない
- 新しいアイデアに懐疑的な人もいるだろう
- 今までもWebにはいろんなアイデアがあった
- しかしそれらのアイデアは、また新たな目標を生み出してきた
- たとえばWordpressでコンテンツを生み出せるようになった
- しかしパフォーマンスとセキュリティの問題が生まれた
- それを回避するためのキャッシュの指定に奮闘した
- それによるパイプラインの肥大化が起きた
- 以下ループ
- そういう過去を踏まえ、簡素化して再構築したのがJamstackである
JAMとは
- JavaScript / API / Markup
- Jamstackとは
- 特定の技術を指す言葉ではない
- いわばムーブメントである
- いろいろなガイドラインがあり、その中で選択をすることになる
- ブラウザのためのJavaScriptは必須になるが、それ以外の言語も使える
- いろいろなOSSを選択できる
- 新しいアイデアもあれば、古いものもある
- 最近になってやっと選べるようになった技術もある
開発効率とパフォーマンス
バージョン管理によるアトミックなデプロイ
- Jamstackでは、コンテンツすらもGitで管理する
- つまりデータベースが不要になる
- この考え方で、常にデプロイがアトミックなものになる
- Gitのブランチを切り替えれば、それがステージングになる
- そういう意味では、もはや静的ではなく、日に数百回も更新される
Jamstackをやっていく
API
- 単なるHTMLよりも複雑なことをやる場合に必要
- 従来はセッションを保持して、サーバーが状態を保っていた
- これらは、専用のマイクロサービスによって代替される
- 支払いはStripe
- 検索はAlgolia
- etc...
- すべてを1回呼びきりで副作用のないAPIにする
- スケーラブルにするため
- とはいえ認証などはあるだろう
- JWTを作成して、ブラウザに保存するとよい
Smashing Magazineのケース
- 歴史あるWebマガジン
- 2017年の末、Jamstackに移行した
- 後の章でそれを解説する
では本編へ
- Jamstackを知るためには、実際にやってみるのがよい
- 特別なスキルは必要なく、既にできることの組み合わせである
- ただしサーバーなしで
- 最初にWebに触れたあの頃を思い出してほしい
- いかに負担をかけずにコンテンツを制作するか
- それが魅力あるコンテンツ、UI作りにつながる
1. モダンWeb開発への挑戦
モノリスアーキテクチャ
- 誰もが通った歴史
- しかしサーバーがクライアントの形まで決めてしまう
- 分離されていないので不必要に複雑化していく
- 現世においては、オーバーエンジニアリングなところすらある
失われた柔軟性
- ここ数年、パフォーマンスへの認識は高まっている
- しかしモノリスなままでは、これ以上の改善がむずかしい
- 開発ワークフローなどにも制限を課されてしまう
パフォーマンスへの関心
- パフォーマンスとコンバージョンには関連がある
- 1秒遅いと売上が7%下がる
- モノリシックなサーバーが、リクエストごとにHTMLを生成するから遅い
- スピードだけがパフォーマンスの指標ではないけども
- キャッシュはパフォーマンスにとって重要
- しかしモノリシックなアプリの場合は、単一のURLから複数のコンテンツが返ることもある
- ログイン状態などにより
- これもユーザーが予測できるようになっているべき
スケールの問題
現状維持のリスク
2. Jamstackとは
その名の由来
- 既にあるものを組み合わせて名付けただけ
- 名前というものは便利
- その背景にあるトレンドとなっている技術たち
- 静的サイトジェネレータ
- SPA
- ビルドツール
- 用途に特化したAPIのエコシステム
- PWA
- etc...
- J: ブラウザのランタイムとしてのJavaScript
- A: データベースを意識しない、個別のHTTPのAPI
- M: 事前にビルド済のHTML
API
- もともとのJavaScriptには、外部のサーバーとやり取りする機能はなかった
- それが今やCORS、WebSocketなどなど
- OAuth2やJWTなど認証の仕組みまである
- APIは、Webの可能性をそのまま広げる
- 今やだいたいのものはAPIでまかなえる
- これを利用しない手はないという意味で、Jamstackでも利用する
Markup
- HTMLはもともと文書を読むためのものだった
- いうなればWebサイトは、ただのフォルダだった
- やがて、データベースの情報を取得して返すものになった
- しかしこれが遅い
- 静的なサイトに比べると複雑になる
- けど、あの頃はそうするしかなかった
- しかし今は違う
- JavaScriptもあるし、クロスドメインでAPIも利用できる
事前ビルド
Jamstackのプロジェクト
- 世界中で様々なタイプのプロジェクトがデプロイされてる
- 数ページのものから、数千ページのものまで
- その種類について見ていく
HTMLコンテンツ
- これももちろんJamstackといえる
- バージョン管理下において、テキストを修正するのみ
- 少し大きな規模になるなら、ビルドツールなどを使えばよい
- コードを変更し、それをプッシュすると、CI/CDで配信される
Webアプリ
- XHRやAjaxからその流れは加速した
- 新たな概念を生み出したという意味で、Jamstackにも親しい
- ページを読み込まずにデータが取得できるというのは革命的だった
- ここ数年であらゆる認識を変えた
*** フロントエンドの分離
- JavaScriptのパフォーマンスが向上したので、SPAができるようになった
- しかし元来のSPAは、単にデータベースを利用するモノリシックなものだった
- RailsでEmberを埋め込んで返すような
- モダンなSPAは、そこが分離している
- もはやバックエンドがいらない
巨大なサイト
- 事前にビルドする際の問題は、そのページ数
- ビルド時間をいかに短くするかが問題
- サイトによっては、10分すらも待てないことがある
- ビルドツールの高速化も進んではいるが・・
- Jamstackを採用できるかどうかは、このサイクルをどう捉えるか
- コンテンツの公開スケジュールに縛られない場合は、多少はマシ
- 数千ではなく、数百万くらいのページがある場合のみ、要検討になると考えている
ハイブリッド
まとめ
- Jamstackがハマらないプロジェクトは、そんなに多くないはず
- ツールやエコシステムが成熟していくにつれて、もっと広まっていくはず
3. Jamstackの優位性
物事を単純化する
- 数多の抽象化によって、我々はいろんなことができる
- しかし抽象化は時に危うい
- 我々の手が届かないところで何が起きているかわからない
よりよい解釈とメンタルモデル
- コンテンツをサーバーサイドで生成するのではなく事前にビルドする
- これによって、ランタイムの環境のことを考えなくてよくなる
- 少なくとも、同時には考えなくてよい
- メンタルモデルがクリアになり、何にフォーカスすべきかが明らかになる
すべてに通ずる必要がない
ランタイムの負担を減らす
- ランタイムで実行するコードも、事前にビルドできる
- 全てではないが
- 何も実行しない = 最速であり、最適化である
- ランタイムでやることが減るということは、障害点も減るということ
- ビルド時のデバッグは、誰にも悪い影響を与えない
- 本当に避けられないもの以外は、サーバーサイドで動的に実行するべきではない
コスト
- コストにはいろんな面がある
- そしてそれはアーキテクチャに大きく依存する
おカネ
チーム効率
イノベーションの価値
- Jamstackでは、小さなパーツをゆるくつなげていく
- パーツはいつでも交換可能である
- リファクタもできるし入れ替えることもできる
- もちろんこれに反して、がっちり接続することもできる
- しかしそれは避けるべき方向性
- 加えた変更による影響が、ビルド時に確認できるのもよい
- ランタイムに影響がない(ことも確認できる)
- トータルで、あらゆるコストが下がるのである
スケールさせるために
- スケールについてもっと詳しく
- どれだけ緻密に見積もっても、サイトのトラフィックは突然跳ねる
- それに備えて監視したり、スケールできるように構成することをしていたはず
- これがそもそもコストであり、好ましい状態ではないということ
そのための静的サイト
冗長性
- CDNにデプロイすることで、冗長性を確保できる
- ビルドとデプロイを分けて考えられるメリットでもある
パフォーマンス
- 開発者なら誰でも、パフォーマンスを気にする必要がある
- ネットワークの信頼性の違いや、回線速度なども
- デバイスの違いについても
- パフォーマンスの指標がある
- FirstMeaningfulPaint / TimeToInteractive
- WPO: WebPerformanceOptimizaion
- https://wpostats.com/
- たくさんの事例が公開されてる
どこから改善するか
- 一昔前は、パフォーマンスのすべてはサーバーサイドにあった
- しかし状況が変わり、フロントエンドでも数々の最適化が成されている
- HTTPリクエストの数を減らす
- メディアの最適化
- etc...
- ブラウザの進歩も相まって改善が見られる
- しかしサーバーサイドはどうか
- 最適化の余地はいたるところにある
- しかし、従来のサーバー構成だと、全てを改善する必要がある
- すべての要素がつながっているから
- Jamstackであれば、そのつながりを断ち、短くすることはできる
- それぞれのエリアで、それぞれが最適化を行うから
- ともあれ、コードを書かないことが最速であることに変わりはない
- サーバーサイドで動的にコンテンツをレンダリングするより
- 事前にビルドされたものをCDNから返すほうが当然早い
必要なものを最適化しておく
- 事前ビルドするからこそ、CDNから即レスポンスができる
- そしてこうすると、ビルド時、デプロイ時のエラーに悩むことはない
- それはユーザーには気付かれないので
セキュリティ
- Jamstackによってシンプルな構成になると、セキュリティも強固になるおまけがつく
露出する面を減らす
- この考え方はセキュリティを考えるときも重要
- 攻撃できる箇所を減らすことができる
- Jamstackに則りスタックをシンプルにするだけで、それが達せられる
読み取り専用にする
外部サービス
- Jamstackでも動的にしたい部分はある
- そういうときにどうするか
*** 複雑性を切り出す
*** 抽象化して切り離す
- APIでまかなえない要件もあるはず
- 外部サービスが要求を満たせない場合
- 外部に預けたくないデータの場合など
- そういう場合は自作するしかない
- それでもJamstackでビルドとデプロイを分けることでメリットがある
- 重要なのはビルドプロセスからのみアクセスできるようにしておくこと
- Jamstackの原則
- 基本的に読み取り専用で露出する面を減らす
- ビルド環境からのみサービスは利用し、外からは見えないようにしておく
- 独立して使える分離されたセキュアなサービスを利用する
どうやって勝つか
- 複雑性を減らすことの意義について学んだ
- 基本的には受け入れられるべき方針だが、もしかしたら開発効率が気になるかもしれない
- 開発効率や開発体験は重要である
- それによってプロジェクトの質も左右される
- 長期的に見ればなおさら
- しかし開発者体験よりも、ユーザー体験のほうが重要
- 開発体験もそこまで悪化しないと思っている
- 馴染みのツールを組み合わせて使うだけなので
- Jamstackは、どちらの体験も良くすることができるはず
4. Jamstackをはじめる
- Jamstackをはじめるにあたってのガイド
- どのようにプロジェクトとコードを管理するか
- どこにコンテンツを保存するか
- なにを使ってビルドするか
- ビルドプロセスの自動化
- どこにサイトを公開するか
- どんなAPIやサービスを使うか
プロジェクトのセットアップ
- サーバーもデータベースも不要な場合、Jamstackはただのフォルダである
- しかしコンテンツはGitで管理されているほうがよい
- たとえ個人プロジェクトだとしても
サイトジェネレータ
- コンテンツを実際のHTMLに変換するところ
- サイトジェネレータはいろいろある
- 昔はJekyll一強だったが今はたくさんある
- https://www.staticgen.com/
- その中からどれを選ぶかが重要
- 選ぶポイントを見ていく
1: サイトの種類
- どんなサイト向けのジェネレータかが暗黙的に決まってる
- ブログ向け、ドキュメントサイト向け、アプリ向けなど
- それぞれのサンプルを実際に触ってみて判断するとよい
3: テンプレートのシンタックス
- Jamstackにおける開発のほとんどは、テンプレートの構築になるはず
- なのでそのシンタックスが開発効率に関わる
- ここは好みが分かれるところのはず
- Jade, Pug, Handlebars, Liquid, etc...
4: ビルドの速度
- コンテンツの変更は即ビルドにつなげたい
- Go製のHugoは、その速さで人気を博している
- クライアントで動くJavaScriptのバンドルを用意する場合などは、どうしても時間がかかる
5: 開発ツール
- サイトはHTMLだけでは作れない
- CSSや画像やJavaScriptのファイルも必要
- それらは圧縮やコンパイルなどの最適化が必要
- ジェネレータによっては、そこまでカバーしているものもある
- ビルドの過程でLintをかけてくれるものもある
- 事前にエラー検知できるので重要
- ローカルで変更をプレビューできることも重要なポイント
- これらを踏まえた上で、自分たちにとってのベストを選ぶ必要がある
- パソコン選びのようなもので、正解はない
自動化する
- Jamstackにおいて、ビルドの自動化は必須
- ビルドして自分でデプロイすることも不可能ではない
- ただすぐにスケールしないことに気づく
- GitのリポジトリからWebHookでビルドを実行するのがよい
- GitHubやGitLabやBitbucketなどにはある
- Gitのpushに対応して、ビルドプロセスを起動する
GiHub PagesやGitLab Pages
自分たちのインフラを使う
- もちろん自分たちのサーバー、VMでビルドしてもよい
- CI/CDに慣れてるなら、Jamstackのビルドは容易い
CDNを選ぶ
- どれだけ技術が進歩しても、時間と空間はまだ克服できない
- コンテンツの提供時間は、ビルドを事前に済ませることでほぼ0にできる
- しかしコンテンツとの空間的な距離は埋められない
- そこで、全世界に配置されたCDNを使う
- CDN事業者の選び方を3つ紹介する
エッジのロケーション
- サイトの利用者に近いところで提供しているものを選ぶ
- いわゆる事業者なら、少なくとも10くらいの地域にはエッジがあるはず
即時アップデート
APIを提供する
- あらゆるものがAPIで提供される昨今
- しかし、それらのAPIが本当に信頼できるのかは悩み
- ただこれは、自作する場合でも同じ悩みになる
- ただ言えるのは、APIドリブンのアーキテクチャや開発手法のほうが柔軟であるということ
- たとえばECサイト
- まず負荷への体制だがこれは問題ない
- そして画面レイアウトなどの柔軟性は、従来のECパッケージを使ったサイトとは比較にならない
- しかしECサイトは動的である
- 検索やセール情報、在庫の確保など
- これらはすべて専用のコンポーネントでまかなう
- ECサイトのビルドの例
- ECサイトのランタイムで動くJavaScript
- このように、APIを組み合わせてサイトを形成していく
5. メンタルモデルの移行
マインドセットとアプローチ
1. CDNを使う
- CDNを利用することで得られるメリット
- 1. 物理的に近いサーバーからコンテンツを配信できてパフォーマンスがよくなる
- 2. 冗長化が自動的に成される
- 3. 自分たちのインフラがSPoFにならない
- 突然のトラフィック増にも、CDN事業者が対応してくれる
- これを自分たちでやるのはすごく大変
- そして動的なコンテンツの場合は、さらに難易度が上がる
CDNを使い倒すには
2. イミュータブルでアトミックにデプロイ
- 事前に静的なコンテンツを用意することで、改善速度もあげられる
- ただしそのためには、たくさんの素材を、すばやくデプロイできなければならない
- リリースサイクルをいかに効率的にするかが、コンテンツが増えると課題になる
イミュータブルにする
- たとえばFTPでサーバーにアップロードする場合を考える
- アップロードの途中で、サーバーの状態が変わることになる(ミュータブル)
- 何か問題があったときに、切り戻しもできない
- 過去のどこで問題が起きたのかもわからない
- よって、変更とデプロイを同じ単位で考える必要がある
イミュータブルにデプロイする利点
- バージョン管理システムの、特定の瞬間を切り出す
- 何にも依存しない、それだけで完結する塊
- それこそがイミュータブルの正体で、それをそのままデプロイする
*** デプロイしたものを把握する
- つまり、何がデプロイされるのかを把握すること
- 何がその環境に配置され、ユーザーに届けられるのか
*** いつでもバージョン切り替え
- ちょっとした変更でも、すべてビルドをやり直す
- 無駄にも思えるが、これが重要
- これにより、ビルドされたものの信頼性があがる
- ビルドプロセスが正常に機能していることの証明でもある
- いつでもロールバックできる
- ランタイムにエラーが発生しても、その影響を最小限にできる
イミュータブルなデプロイの位置づけ
- Jamstackに移行することは、イミュータブルなデプロイを行うに等しい
- ビルド時に利用するデータと、その後で利用するAPIも分離されてる
- これらの性質があるからこそ、イミュータブルなデプロイが可能になるとも言える
アトミックなデプロイ
- イミュータブルに生成されたコンテンツは、アトミックにデプロイされる
- アトミックなデプロイとは、すべてをまとめてデプロイすること
- 変更した一部分の差分だけを更新するのではなく
- CDNはファイルの差分をハッシュなどでチェックでき、無駄なファイル転送を省いてくれる
- Jamstackは、こうした前提に基づいて、あらゆる複雜性を排除するデザイン
3. すべてをバージョン管理する
- コードベースの管理に、Gitを採用することは一般的
- だがその考え方をデプロイにまで活かすことは、あまりされていない
- Herokuはそれをやっている例で、人気を博した
- デプロイまでバージョン管理下に置くことで、不慮の事故を防ぐことができる
- ステートフルなデータベースがあるとそれも難しいが、Jamstackにデータベースは存在しない
オンボーディングのコストを減らす
- バージョン管理されていれば、新人が歴史をたどることもできる
- 新人が仕事をはじめるまでの理想の流れはこう
- コードへのアクセス権をもらう
- `README`などを読む
- ローカルにコードをクローンする
- 依存関係を1つのコマンドでダウンロード
- 1つのコマンドでビルドして確認
- 1つのコマンドで任意の環境にデプロイ
- `README`のほか、`package.json`なども昨今は便利な道標になる
4. 自動化とツール
- 単なる静的なサイトでなく、ビルドとデプロイの自動化までやるのがJamstackのカギ
- 静的サイトジェネレータを使うことは、そもそもその自動化への第一歩でもある
サイト生成のパターン
リスク削減のために人間にやらせない
- 自動化することで、人間のミスを減らすこともできる
- 繰り返しの処理を、後から自動化することはよくある
- ただし後からではなく早い段階でやってしまうことをおすすめする
5. エコシステムを利用する
- 価値があり、利用できるツールは、どんどん利用していく
- 便利なツールやサービスが急速に生まれている
- Jamstackを、単なる静的なサイトのためのアプローチと言えなくなりつつある
- これらのツールやサービスを利用することで、機能追加し動的にできるから
- そんなサービスを、Jamstackのプロジェクトで採用するためのポイントを紹介する
フォーム
検索
- 簡単な検索であれば問題にならない
- ただ、場合によっては複雜になり得る
- 静的サイトジェネレータは、出力フォーマットを変えられるはず
- それで検索用のインデックスを生成して、検索用のサービスに送る
- そしてそれを、クライアントのJSで索引すればよい
- それだけでなく、付加価値を提供するサービスもある
- Algoliaなど
- そのほか、GoogleやDuck Duck Goで、サイト内検索を提供することもできる
- JSが使えない環境でも利用できるし、実装コストも軽い
通知
- ユーザーに連絡するためには、しばしば複雜な仕組みが必要
- できればこれもサービスでなんとかしたい
- メール
- SendGrid, Mailgun, ...etc
- Twilioは、SMSや音声通話などもAPIで提供している
認証
- 認証と認可をどうするか
- 特に個人情報を扱うためには、細心の注意が必要
- しかし場合によってはアウトソースできない事情もあるはず
- ただベストプラクティスが確立されつつある
- IDベースで認証や認可をする仕組みを使う
- これにより直接ユーザーの個人情報を管理する必要がなくなる
- そんなOAuthのサービスとしては、Auth0などがある
6. FaaSで最後の穴を埋める
- これまで見てきたように、たくさんのサービスがある
- 基本的にそれらを再実装する必要はない
- とは言え、どうしても実装する必要がある場合もある
- そこで使えるのが、Functionのサービス
- サーバーレス関数とも
脱モノリスするために
- Web開発者は、その速度を落とすことなく学び続けなければならない
- ただ、すべてのことに精通する必要はない
- 外部サービスを利用するということは、責任を預けるということ
- 最初はそれが落ち着かないかもしれない
- ただし、そうすることで得られるものも多い
- 安心感、開放感なども
- 彼らも素人ではない
- 自分たちの領域にその分だけ集中できる
- どの領域を3rdパーティのサービスに任せるかは、一考の余地がある
- 利用規約は適切か
- サービスレベルの保証はあるか
- 金銭的なコスト、実装のコストはどうなるか
- ただ基本的な考え方として、事業者もビジネスでやっていて、常に進歩している
- 自分たちで実装するよりも、任せてしまうほうが、往々にして良い結果になる
- 次の章では、それを実践した経験について触れる
6. Jamstackを適用する
ケーススタディ: Smashing Magazineの場合
- Smashing Magazineは歴史あるフロントエンドの情報サイト
- 2017年の末、Jamstackに移行した
- この章は、そのショーケースである
チャレンジ
- サイトは10年も運用されていた
- 数千もの記事、20万のコメントがあるWordpressの本体
- 本やワークショップを販売するShopifyのEC
- Ruby on Railsでできたジョブボード
- カンファレンス用のPHPのスタック
- ビジネスの成長にあわせて様々な機能が追加されてきた
- しかし、もうこれ以上は厳しいという段階だった
キーポイント
- パフォーマンスと安定性、セキュリティを改善したい
- 同時に、メンバーシップの概念を導入したかった
パフォーマンス
- 同様に、パフォーマンスへの取り組みも分散していた
- 各言語ごとのライブラリやモジュールとして
- 管理する対象が多くて、セキュリティ的な不安もあった
メンバーシップ
- 新たな機能であり、リデザインのモチベーションでもあった
- メンバーシップによって得られる機能
- 広告無し
- ディスカウント
- 相応のUI表示など
ツール選び
- それらを実現するため、選ばれたのはJamstackでした
- そのコアとなる静的サイトジェネレータや、フロントエンドのフレームワークを選ぶ
静的サイトジェネレータ
アセット管理
- ブラウザに最適化されたアセットを届ける必要がある
- だいたいの静的サイトジェネレータは、その機能を含んでいたりする
- しかしHugoにはない
- 必要だったのは、JSのバンドル、コード分割、SCSSのコンパイル
- webpackを検討した
- JavaScriptの扱いは十分だった
- しかしCSSのそれは、静的サイトというよりSPA向けの機能だった
- HTML/CSSに長けたメンバーがいたので、その開発体験は損ねたくなかった
- 結果、Victor Hugoというフレームワークを自作することにした
- https://github.com/netlify-templates/victor-hugo
- GulpでSassとHugoをコンパイルし、JSはwebpackで更新する
コンテンツの移行
コンテンツの構造
大規模サイトであるがゆえ
- Victor Hugoに移行してからの開発で問題になったことが1つある
- テンプレを変更した際の自動リビルドが遅いこと
- それを回避するため、Gulpを導入してスクリプト化した
- 作業時には、すべてではなく100くらいのビルド済の記事で構成されるサイトとした
- こうすることで、ローカルでの開発にHugoで毎回ビルドする必要がなくなった
コアを作る
検索
- 検索は事前にビルドできない
- ここではSaaSとしてのAlgoliaを利用した
- 競合としては、Lunrがあった
- こっちはインデックスを生成して、静的なファイルとして利用できる
- ただ大規模サイトには向かないと判断
- ビルドの過程で、Algoliaへインデックスを送信するようになっている
- フロントエンドはPreactとReduxで構成
- `data`属性がついた要素に、Preactのアプリを描画する
- JavaScriptが使えない環境では、Googleのサイト内検索にフォールバック
コンテンツ管理
- Jamstackでのコンテンツ管理は、いろいろなやり方がある
- しかし中でも、ヘッドレスCMSの利用が革新的
- https://headlesscms.org/
- 種類としては、APIベースのCMSと、GitベースのCMSに大別される
- APIベース
- Gitベース
- APIベースの利点は、さまざまなクライアントに、さまざまなデータを返せること
- ただし、データの整形の手間が必要で、事前ビルドの時間が増える
- Gitベースの利点は、ディレクトリがそのままソースになるところ
- 普段使っているツールやスクリプトがそのまま使える
- Smashing Magazineでは、Netlify CMSを選んだ
- ビルドの時間が短くなる
- 普段使いのエディタでコードのようにコンテンツを編集できるのがよい
Netlify CMS
大規模サイトのためのCMS
ユーザーとロール
- モノリシックな構成の場合、ユーザーの認証ももちろん組み込まれているはず
- Smashing Magazineでも、複数のサイト向けに別々のユーザーの概念があった
JWTを使ったステートレスな認証
- 従来の認証は、セッションIDをCookieに含めて利用することが多かった
- それによりサーバーでステートフルにユーザーを管理していた
- ステートレスな認証フローでは、代わりにユーザーの情報を送信する
- これにより、各サービス側が、独自に必要な情報をチェックして認証することができる
- このユーザー情報をどのように画一的に扱うかが問題
- そのために存在するのがJWTである
- Auth0がこの領域には詳しく、説明用のサイトもある
*** GoTrueによる認証
- Smashing Magazineでは、GoTrueというOSSのマイクロサービスを使った
- https://github.com/netlify/gotrue
- `/signup`などのエンドポイントが立てられる
- クライアントではJavaScriptからこのSDKを利用する
- ログインユーザーは`LocalStorage`に保存した
EC
- Smashing Magazineの収入を支えるのがEC
- これまではShopifyを使っていたが、今回の移行で、GoCommerceというOSSを作った
- https://github.com/netlify/gocommerce
- 商品カタログのパスを渡して購入状態を作るAPIと、その購入に対する決済トークンを用意するAPI
- 決済方法はPayPalかStripeから選べる
- ビルド時に商品のカタログをHugoで生成し、それを利用する
- Preactのフロントエンドでカート情報を保持しつつ、裏でそのAPIを叩く
- 購買フローを自由に設計できるのが強み
- この仕組みはデモのリポジトリもある
ユーザーと注文
- GoCommerceも、他のサービスと同じで、JWTによって認証できる
- これによって、認証済のユーザーのみが購買できる
- 購買履歴を返すこともできる
メンバーシップとサブスク
- Smashing Magazineには、3段階の購読プランがある
- それによって、今まで紹介してきた各機能が協調するようになる
- そのための橋渡しをするために、AWSのLambda関数がある
- 購読のタイミングで、ユーザーを認証する
- そしてメールの購読サービスに登録し、Slackに通知
- Stripeで定期購読するよう設定する
- 最後に、認証サービスのユーザー情報も更新する
- これらの処理はシークレットの問題で、クライアントサイドではできない
GoCommerceでメンバー割引
ジョブボードとチケット
サービスのデプロイと運用
- それまではHerokuにすべてをデプロイし、DBもそこに1つだけあった
- この構成に変えてからは、各サービスがそれぞれのデータを抱える
- マイクロサービスの連携において、共通のDBを持つことは推奨されない
- それぞれのサービスを橋渡しするサービスも、最終的にAWSのLambda関数になった
- それより大きな規模であったり、永続化層が必要な場合は、Kubernetesなどに移行するのがよさそうである
7. まとめ
最後にもう1つ
- Jamstackの利点だけを並べて説明するのは容易い
- しかしそそれ以上に、大事な哲学があることに触れておきたい
- Jamstackは、真にWebのためのものである
- iPhoneが世に出たあとで、ジョブズはFlashをHTML5に置き換えた
- そのときに、Adobeに向けた手紙を書いている
- だいたいこんな内容
- Webは誰の手も借りずに、コンテンツを公開できる唯一の場所
- しかしそこで十分な品質やUXを提供できない場合
- またFlashの二の舞になってしまう可能性がある
- GoogleのAMPなどの取り組みもあるが、あるべき姿ではない
- Webの競争力を、健全なWebを保つために、過去の問題を解決しつつ、前に進む
- そのためのベストプラクティス、ガイドラインであり制約であるのが、このJamstackである
現場からは以上です!
ちなみに、Jamstackな会社のサイトでもわかりやすく説明されてたりするので、よければそちらもどうぞ。(宣伝)