超高速！ GatsbyとCMSで作る新しいサイトのカタチ

[Drupal Camp DEN Japan](https://drupal-camp2018.den-japan.org/)というイベントで話した内容 + アルファです。

発表のスライドは[こちら](https://speakerdeck.com/7tsuno/chao-gao-su-gatsby-plus-decoupled-drupaldezuo-ruxin-siisaitofalsekatati-185dbd07-a848-490b-acb5-51b015f92051)

イベントではDecoupled Drupalとして話しましたが、Headless(Decoupled)CMSなら他でも可能です。
WordpressとDrupalとContentfulを試しましたが個人的にはDrupalがかなり感覚的に細かくいじれて好きです。

## Gatsbyとは？

React.js製の静的サイトジェネレータです。
超高速なページ遷移がすごいやつです。
最近エンジニアさんのブログとかでよく使われていたりするのかなと。
いろんな使い方があるのですが、今回はDrupalがテーマなので

**CMSに登録されたデータをもとに静的サイトを作ることが出来る！**

というところに焦点を絞って書いていきたいと思います。

## 何がうれしいのか

### いままでのCMS

![image.png](https://qiita-image-store.s3.amazonaws.com/0/154239/d2e0175b-62df-9608-cab3-aeb02e948f1e.png)

DecoupledなCMSではないCMS(ここではいままでのCMSと書かせてもらいます。)では、フロントエンドとバックエンドが分離していない状態でした。

大まかに表すと、

* 管理者はCMSにアクセスしてコンテンツのデータを登録・更新する。
* エンドユーザはCMSにアクセスしてコンテンツのデータを参照する。

というような構造になっています。

### 今までのCMSでの問題点

管理者もエンドユーザも同じCMSを見に行くため、以下のようなセキュリティ上の問題が存在していました。

* HPのログイン画面が通常ユーザでもアクセスできてしまうため、ID・パスワードが漏洩した場合に不正アクセスされてしまう可能性がある。
* CMS自体にセキュリティホールがあった場合にも同様に、不正アクセスされてしまう可能性がある。

また、CMSに完全に依存する作りであったため、以下のような問題もありました。

* CMSが落ちたり、壊れたりした場合に、サイトが参照できなくなる。
* CMSのサービスが終了すると使えなくなる。(Drupalはまだ心配ないと思いますが)

ページキャッシュで問題は幾分か解決されるものの、性能面での問題もあります。

* ユーザがアクセスするたびにコンテンツのデータを検索し、取得するためページ表示が遅くなる。

### Decoupled CMSなら...？

![image.png](https://qiita-image-store.s3.amazonaws.com/0/154239/ce4b2438-49d0-00fc-8dcc-4055ab8f4578.png)

Decoupled CMSでは、フロントエンドとバックエンドが分離している状態になります。

大まかに表すと、

* 管理者はCMSにアクセスしてコンテンツを登録・更新する。
* エンドユーザはフロントエンドにアクセスしてコンテンツを参照する。

というような構造になっています。

この構造はもちろんIoTやネイティブアプリなどで同じAPIが使えたり、フロントのデザインの自由度を上げることができるなどいくつかの利点がありますが

**先ほど挙げた問題はほとんど解決することが出来ません。**

エンドユーザはバックエンドにアクセス可能なため、セキュリティの問題は消えません。(下手にDecoupledにしてしまうとAPIの品質問題などでむしろセキュリティのリスクは上がってしまいます。)

結局API経由でコンテンツを参照しているため、CMSが落ちるとデータの参照はできないですし、データ検索は行われるため性能も変わらないです。

### Gatsby + Decoupled CMSなら

![image.png](https://qiita-image-store.s3.amazonaws.com/0/154239/f4507255-6897-aef0-7207-cf6ccc717877.png)

さっきの絵と変わらないやんけ！って思うかもしれないですが、
最大のポイントは

**フロントエンドとバックエンドがつながっていないこと**

にあります。

つまりどういうことかというと、
エンドユーザがフロントエンドを触っても、バックエンドにコンテンツのデータを取りに行くことがありません。

**バックエンドが完全に分離されている**

ということになります。

バックエンドは管理者しかアクセスしなくできるため、CMSの乗っているサーバ自体にIP制限をかけることができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/154239/0641051c-ef92-b090-f011-129459090188.png)

管理者のIPしか受け付けないように設定するなどをすれば、エンドユーザがバックエンドに触ることはできなくなります。

バックエンドに触れることが出来ないため、セキュリティの問題は解決します。
また、バックエンドからデータを取得しないため、CMSが落ちたり、サービス終了してもユーザがサイトが参照できなくなるということもありません。
バックエンドからコンテンツのデータを取得しないため、アクセスのたびにデータ検索を行って性能問題が発生することもありません。

## 一体何が起きているのか？

ただそもそも、

* コンテンツのデータを取得しないってどういうことなのか？
* せっかく管理者がコンテンツを登録しても参照できないのでは？

と思うはずです。

### Gatsbyのしくみ

Gatsbyがビルドを行うと、静的サイトが作られます。
**ビルド中にCMSにアクセスを行い、コンテンツのデータを取得します。**

発想の転換なんです。

いままで、ページにアクセスするたびにコンテンツのデータを取得していたものを
ビルド時に一度だけデータを取得して、コンテンツのデータを埋め込んだ状態でページを作ったあげるというようなことをしてくれると。

出来上がった静的ページにはすでにコンテンツのデータが埋め込まれているので、それをデプロイすればエンドユーザはCMSに登録されたコンテンツを参照することが出来るというわけです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/154239/bad1a1a6-df70-cb11-481f-cba3b07dca1b.png)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/154239/a5f11729-a972-25de-d782-af5f9bd3b545.png)

ん？でも

管理者がバックエンドを更新するたびにビルドし直してデプロイし直すの大変じゃない？

## Netlifyを使う

Netlifyというのは、高機能ホスティングサービスで
静的サイトのビルド・デプロイ・ホスティングが可能で、かつ基本機能は無料というすごいやつです。

NetlifyはWebhookでビルドコマンドを叩くことが出来るので、CMSの登録・更新からのWebhookでこいつを叩いてあげれば自動で更新される仕組みを作ることができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/154239/eb8cd856-c5cb-a11a-ce38-4da83e45fe20.png)

数100件のデータであれば5分程度でビルドは終了します。
件数が増えた場合には何か対策が必要だと思います。

## メールフォームなどはどうする？

コンテンツ管理以外の動的な部分についてはこの構造単体だと実現できません。
Netlifyにはフォーム機能があるためそれを使うか、[別の記事](https://qiita.com/7tsuno/items/7205970d9b8ef79d7f56)で紹介したような外部APIを使うか、それだけは自分で作るかが必要だと思います。