[環境構築] HeadlessCMSのstrapi + MySQL + GraphQLでローカルにDockerで環境を構築しました


これが初投稿なので誤字脱字なんかは優しくしてください（？）

今回HeadlessCMSを触る機会があったので、strapiを触ってみました。
strapi以外にもいくつか触ったので、後ほど記事にできたらいいなと思います。
また、今回フロントエンドとの連携は記載していないので、後ほどそちらも記事にしたいと思います。

##参考URL
- [公式サイト](https://strapi.io/)
- [公式Github](https://github.com/strapi)
- [Qiita「Strapi (Headless CMS)を使ってみたので使い方まとめ + GraphQL」](https://qiita.com/mtoyopet/items/46d3f6edbaaed4f0065c)

##はじめに
###HeadlessCMSとは
今回使うHeadlessCMSとは異なる[microCMS](https://microcms.io/blog/what-is-headlesscms/)のエンジニアブログで記載があるので引用します。


>ヘッドレスの「ヘッド」は、ビュー（表示する画面）を指します。
>ヘッドレスなので、ビューの無いCMSということになります。

とのことです。
Wordpressを筆頭とする従来のCMSはコンテンツを入稿するシステム画面＋入稿したコンテンツを表示する画面が合わさったものですね。
そこからコンテンツを表示する画面がなくなったものがHeadlessCMSです。

なんとなくイメージはついたでしょうか？

###どうやってコンテンツを表示するのか
従来のCMSとは異なり表示する画面がない為、
HeadlessCMSは入稿したコンテンツをAPIで取得することが可能です。

APIだけでなくGraphQLも使えたりと従来のブログとしての利用だけではなく、
簡易的なDB操作のAPIであれば管理画面から作れます。
やっていて思ったのが
DBはあるけどバックエンドのシステムがまだできていないという感じであれば、簡易的なAPIを作成してフロントの開発ができたり・・・？
みたいな使い方ができたりしそうな印象を受けました。

###今回の構成
strapi + MySQL + GraphQL

今回調査するにあたって、MySQL + GraphQLで使えることが必要だったので、それで使えるところを探しました。
strapiとしてはPostgresやSQLiteなんかでも使えるのでご自分の環境に合わせてぜひ使ってください。
また、GraphQLを使っていますが通常はRestAPIで動作するのでそちらも使いたい環境に合わせてください！

##環境構築
###今回使用する環境
MacBookPro: OSX Catalina 10.15.5

###Dockerの用意
Docker for Mac（WindowsやLinuxの場合読み替えてあげてください）を用意してください。
dockerコマンドを叩くので叩ければそれでよいです！

公式のGithubに設定が載っているのでそれをそのまま使用します。
（僕がまだDocker勉強中なので細かいところはご説明できませんでした・・・）

[各DBごとのdocker-compose.yml](https://github.com/strapi/strapi-docker/tree/master/examples)

僕の場合はMySQLを使う必要があるのでMySQLフォルダのymlファイルを使います

```docker-compose.yml
version: '3'

services:
  strapi:
    container_name: strapi
    image: strapi/strapi
    environment:
      - DATABASE_CLIENT=mysql
      - DATABASE_HOST=db
      - DATABASE_PORT=3306
      - DATABASE_NAME=strapi
      - DATABASE_USERNAME=strapi
      - DATABASE_PASSWORD=strapi
    ports:
      - 1337:1337
    volumes:
      - ./app:/srv/app
    depends_on:
      - db

  db:
    container_name: mysql
    image: mysql:5.7
    restart: always
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_DATABASE: strapi
      MYSQL_USER: strapi
      MYSQL_PASSWORD: strapi
      MYSQL_ROOT_PASSWORD: strapi
    volumes:
      - ./db:/var/lib/mysql
```

###Dockerコンテナの作成
ファイルが用意できたらコンテナを作成します。
特に希望がない方はREADMEに記載があるのでコマンドを叩きます

```
$ docker-compose up
```

しばらく待機するとmysqlとstrapiのコンテナが立ち上がり
`http://localhost:1337/admin`
でアクセスできるようになると思います。
<img width="1439" alt="スクリーンショット 2020-07-16 11.57.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488594/25098649-1280-5175-3a22-7a6aa580210b.png">


###GraphQLのインストール
ここまでできたら次はGraphQLを用意します。

```
$ docker exec -it strapi /bin/bash
```

dockerのコンテナの中にアクセスし以下のコマンドを入力

```
$ strapi install graphql
```

しばらく待つとGraphQLのインストールが完了しますので、

`http://localhost:1337/graphql`

にアクセスするとこんな感じの画面が立ち上がります。

<img width="1439" alt="スクリーンショット 2020-07-16 11.54.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488594/57791a49-0953-4dcc-f402-a9f21fdc1b43.png">

これで環境構築は完了です。

##実際に使ってみる
###テーブルの作成
最初のログイン画面みたいなところは適当でOKです（バリデーションはあるのでそこは考慮してください）
そうするとダッシュボードが立ち上がりますので、プラグインのコンテンツタイプビルダを選択します
選択したらCreate new collection typeを選択します。

これがDBのテーブルになるので任意のテーブル名を設定してください。

<img width="1439" alt="スクリーンショット 2020-07-16 12.12.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488594/a9420993-c049-a030-75dd-90f944747d23.png">

その後カラムの設定に移ります。

<img width="1439" alt="スクリーンショット 2020-07-16 12.13.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488594/5d912896-8acd-37ce-de68-7a14d7e7ca92.png">

カラムの設定はSQLを書いたことある人はなんとなくイメージつくと思うので省きます。
とりあえず今回はTextのみを設定しました。
テーブルのりレーションなども作れるので自由に設定してください。

完了したらダッシュボードの右上の保存を押しテーブルの作成を完了します。

###データの作成
サーバが再起動した後に確認するとダッシュボードのメニューに先ほど作成したテーブルが出てきます。
今度はそちらを選択すると今登録されているデータが表示されます（初回は何もでないと思いますが）

右上に追加ボタンがあるので選択するとデータ追加画面に移動します

<img width="1439" alt="スクリーンショット 2020-07-16 12.26.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488594/17ba51b6-dfef-5657-1c29-c153254a1fe4.png">

データを追加するとデータの表示画面に表示されるようになります。
今回は任意で入れたカラムが１つだけなのでちょっとあれですが複数あればそれようの登録画面が表示されます。
また、IDや登録日時などは自動で設定されるので、使いたい場合は既にあるものを使ってください。

<img width="1439" alt="スクリーンショット 2020-07-16 12.27.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488594/660d5ef6-5ed4-ebdb-e86b-750ee646431a.png">

###APIの公開設定
データを登録しましたがこのままではAPIを使えません。
次はAPIの公開設定を行います。
ダッシュボードのメニューから「プラグイン→ロールと権限」を選択します。

そこからPublicを選択します
Publicを選択すると下の方に権限設定があると思います。
各テーブル単位で許可する権限が設定できます、。
findで全検索、findoneで１件の検索を許可するなど必要な権限を設定してください。

<img width="1439" alt="スクリーンショット 2020-07-16 12.33.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488594/c0722564-b562-368d-5b34-01a20755e361.png">

選択し右上の保存を押すとAPIが使えるようになります。
使い方は右側のグレーのエリアに出ていると思います。
僕の環境ではテーブルが「Content」なので、以下のURLでfindが使える様になります。

`http://localhost:1337/contents`

ブラウザからアクセスするとこんな感じです

<img width="1439" alt="スクリーンショット 2020-07-16 12.37.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488594/577ddb7f-c4c3-a626-7d1d-1e141080f362.png">

```response(仮).json
[
  {
    "id": 1,
    "Title": "Sample",
    "created_at": "2020-07-16T03:26:19.000Z",
    "updated_at": "2020-07-16T03:26:19.000Z"
  }
]
```
データが取れる様になりました。
画面側から使う場合はajaxなどを使って取得することになると思います。
また更新や削除などの権限もあるので使いたい権限のみを許可してください。

###GraphQLを使ってみる
それでは次にGraphQLで検索処理を実行してみたいと思います。

`http://localhost:1337/graphql`

こちらにアクセスしてください。
GraphQLの使い方はご自身でぜひ調べてみてください。
（僕もあんまり知らないので・・・）

今回は以下のクエリを設定しました。

```
query findContents {
  contents {
    id
    Title
  }
}
```

再生ボタンみたいな三角のボタンを押すとこんな感じで結果が取得できました。

<img width="1439" alt="スクリーンショット 2020-07-16 12.46.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488594/47b27555-e7f0-e2d2-a029-1b670c7fd858.png">

GraphQLも使えるようになりました。
あとは実際に使いたいデータを登録していき画面に表示するだけです。

##まとめ
今回はサーバ側の環境を作ってみました。
サーバサイドの言語を使ったことがない人としてはこんな感じで簡単にデータが作れるとかなり便利なのではないかと思いました。

次は実際にフロントで表示するところをまとめられたらと思います（気力があれば・・・）。