Help us understand the problem. What is going on with this article?

Strapi (Headless CMS)を使ってみたので使い方まとめ + GraphQL

とよももです!
お仕事でHeadlessCMSのstrapiを触る機会がありました。情報が少なくて苦労したので、誰かの助けになる様にまとめたいと思います。

ちなみにvue + strapiでアプリを作ってみました。axiosでgraphqlを使いたい方など、参考に見てみてください。
レポジトリ

Strapiでの認証方法記事も書きました。
Strapiに認証機能を追加する(特定のユーザしかAPIが呼べない仕様に変更する)

事前知識

CMSとは

CMSとは、Contents Management Systemの略です。CSSやHTMLなどのWEBサイトを構築するための専門的な知識を持っていなくてもWEBサイトやコンテンツを構築し、管理ができるシステムです。

最も代表的なCMSは「WordPress」。「はてなブログ」や「Qiita」、「Note」もCMSです。

CMSを使うことで、簡単にWEBサイトを構築できます。詳しくは下記の記事がわかりやすいです。
CMSとは?初心者でもわかるCMSの基礎知識とメリット、導入事例

Headless CMSとは

コンテンツを管理するバックエンド側だけを提供するのが「Headless CMS」です。

ここでいうヘッド(Head)というのは、画面に表示するビュー(フロントエンド)のことです。ヘッドレス(Headless)なので、フロントエンド側のないCMSということになります。

従来のCMSは、コンテンツを作って管理するバックエンドと、コンテンツを表示するフロントエンド、2つの機能があります。Headless CMSは、コンテンツを制作して管理するバックエンドしかありません。そのため、APIとしてHeadless CMSを使用することで簡単にコンテンツを管理できます。

Headless CMSの説明についてはこちらの記事がとてもわかりやすいです。
ヘッドレスCMSとは何か?従来CMSとの違いやメリデメを解説!

Strapiセットアップ

では早速Headless CMSのStrapiを触っていきたいと思います。
image.png

Strapiをインストール&新規プロジェクトを作成

下記コマンドを実行してstrapiをインストールします。

$ npm install strapi@alpha -g

次に、strapiアプリを新規作成しましょう。

$ npx create-strapi-app my-project --quickstart

// または
$ yarn create strapi-app my-project --quickstart

管理者アカウントを作成

インストールが終わると、Strapiのアカウント作成画面が自動で開くので、登録を完了させます。自動で開かない場合は、http://localhost:1337/admin にアクセスします。
image.png

ローカルサーバを動かすコマンド

万が一ローカルサーバを止めてしまったら下記のコマンドで動かしてください。

$ npm run develop

コンテンツタイプの作成

いきなりコンテンツタイプと出てきて混乱してしまいますが、通常のデータベース

  • コンテンツタイプ → テーブル名
  • フィールド → カラム名
  • エントリー → レコード

だと思って進めるとわかり易いです。

初めてのコンテンツタイプを作成

まずは「テーブル名」となるコンテンツタイプを作成していきます。
本記事では、「Restaurant」というコンテンツタイプを作成します。また、「name」と「description」という2つのフィールドを作成します。

左側のタブから「コンテンツタイプ作成」→「Create new content-type」を選択します。
Display Nameを入力し、「続ける」を押下します。ちなみに、Display Nameは単数形で問題ありません。Strapiが自動で複数形に直してくれます。
image.png

content typeフィールドを選択し、名前を入力し「Finish」を選択します。今回は「text」タイプの「name」というフィールドを作成しています。
image.png

最後に、画面右側に詳細が表示されるので、保存ボタンで上書きしましょう。

エントリーを作成

次に、レコードとなるエントリーを作成していきます。左側のタブからRestaurantsを選択し「Restaurantを追加」ボタンを選択します。
レストラン名と詳細を入力し保存すると、レコードが作成されます。

image.png

権限の設定

CRUD操作を行うには、別途権限を付与する必要があります。設定を行ってない場合は、APIを呼び出しても404エラーになってしまうのでこの設定は忘れない様にしてください。

左側のタブから「ロールと権限」を選び、「Public」を選択します。Restaurantの「findone」にチェックをいれるとレストランを1つだけ呼び出すためのAPIのURLが右側に表示されます。あとで「create」「update」「delete」もやるので、全てにチェックを入れておきましょう。

image.png

保存をして、 試しに localhost:1337/restaurants/1 にアクセスしてみます。
取れた!
image.png

GraphQLを使ってCRUD操作を行う

プラグインを導入

GraphQLはデフォルトで入っていないため、プラグインとして別途導入する必要があります。

$ strapi install graphql
// ↑でインストール後エラーが出る場合、
// $ strapi uninstall graphql コマンドでアンインストールし、
// ↓のコマンドで試してみてください

//または
$ npm run strapi install graphql

//または
$ yarn strapi install graphql

導入が完了したら、 http://localhost:1337/graphql にアクセスします。
こんな画面が出てくるはず!ここでGraphQLをいじってデータを取ったり新規作成したりできます。
image.png

Graphqlの使い方を簡単に紹介

やりたいこと
・データを読み取るだけの場合は「query」を指定する
・データを修正したり新規作成などの編集を行う場合は「mutation」を指定する

CRUD操作の名前とコンテンツタイプ名
・get/create/update/deleteのどれかの後に、操作したいコンテンツタイプ名を指定する
・CRUD操作名は小文字から、コンテンツタイプ名は大文字から始める
・ここを間違えると動かないので注意

# 構文:

やりたいこと(query/mutation) CRUD操作の名前とコンテンツタイプ名 {
  コンテンツタイプ名(id: id) {
      id
      name
      description
    }
  }

# 例えば: idが1のrestaurantのid・name・descriptionを取りたい時
query getRestaurants {
  restaurant(id: 1) {
      id
      name
      description
    }
  }

注意点

やりたいこと(queryまたはmutation)の後に続くCRUD操作の名前とコンテンツタイプ名は、GraphQLの決められたルールに基づいています。適当につけているわけではありません。

これを間違えるとCRUD操作が動かないので注意してください。

GET:レストランを一つだけ取ってみる

idが1のRestaurantを取り出してみます

query getRestaurants {
  restaurant(id: 1) {
      id
      name
      description
    }
  }

取れた!
image.png

CREATE: Restaurantを新規作成する

mutation {
  createRestaurant(input: {
    data: {
      name: "みっちゃん",
      description: "広島で有名なお好み焼き屋さん"
    }
  }) {
    restaurant {
      name
      description
    }
  }
}

image.png

無事できてるっぽい!
image.png
image.png

DELETE:Restaurantを削除する


mutation {
  deleteRestaurant(input: {
    where: {
      id: 3
    }
  }) {
    restaurant {
      name
      description
    }
  }
}

UPDATE:Restaurantを編集する

mutation {
  updateRestaurant(input: {
    where: {
      id: 26
    },
    data: {
      name: "モスバーガー"
    }
  }) {
    restaurant {
      name
    }
  }
}

image.png

Herokuにデプロイする

デプロイの準備

StrapiをHerokuにデプロイする方法です。詳しくは「公式サイト」にめちゃくちゃ丁寧な解説が載っています。詳しく知りたい方は公式ページを読みながら進めることを強くお勧めします。

デプロイの前に下記を行ってください。
・Gitをインストール
・Herokuアカウントの新規作成
・Heroku CLIのインストール

Gitを有効化、最初のcommitをしておきます。

$ cd my-app
$ git init
$ git add .
$ git commit -am "Initial commit"

Herokuアプリを新規作成します。

$ heroku create

image.png
この時点で、自身のHerokuアカウントを覗くと、アプリが作成されているはずです。

Postgresのアドオンを追加する

ローカルではsqliteを使用していましたが、Herokuでは今回はPostgresqlを使っていきます。HerokuのアドオンにPostgresを追加します。

$ heroku addons:create heroku-postgresql:hobby-dev

image.png

環境変数を設定する

heroku configを打つと、今入れたPostgresデータベースの情報が出てくると思います。
例:DATABASE_URL: postgres://ebitxebvixeeqd:dc59b16dedb3a1eef84d4999sb4baf@ec2-50-37-231-192.compute-2.amazonaws.com: 5432/d516fp1u21ph7b

これをもとに環境変数を設定していきます。
postgres:// USERNAME : PASSWORD @ HOST : PORT : DATABASE_NAME

$ heroku config:set DATABASE_USERNAME=ebitxebvixeeqd
$ heroku config:set DATABASE_PASSWORD=dc59b16dedb3a1eef84d4999a0be041bd419c474cd4a0973efc7c9339afb4baf
$ heroku config:set DATABASE_HOST=ec2-50-37-231-192.compute-2.amazonaws.com
$ heroku config:set DATABASE_PORT=5432
$ heroku config:set DATABASE_NAME=d516fp1u21ph7b

:warning: ⬆️のデータベースは既に削除してます。本来であれば機密情報なので、⬆️のように大衆が見る場所にデータベース情報を晒さないよう、十分注意してください。

database configファイルの修正

./config/environments/production/database.jsonの中身を下記の様に置き換えます。

database.json
{
  "defaultConnection": "default",
  "connections": {
    "default": {
      "connector": "bookshelf",
      "settings": {
        "client": "postgres",
        "host": "${process.env.DATABASE_HOST}",
        "port": "${process.env.DATABASE_PORT}",
        "database": "${process.env.DATABASE_NAME}",
        "username": "${process.env.DATABASE_USERNAME}",
        "password": "${process.env.DATABASE_PASSWORD}",
        "ssl": true
      },
      "options": {}
    }
  }
}

pgモジュールをインストール

PostgreSQLのStrapiをインストールしていない場合は、下記コマンドを実行してpg nodeモジュールをインストールします。

$ npm install pg --save

最後にデプロイ!

準備が整ったら、最後にHerokuにstrapiアプリをデプロイしましょう。

$ git commit -am "database設定をアップデート"
$ git push heroku master

image.png

「herokuアプリのurl/admin」にアクセスすると、productionの管理画面にアクセスすることができます。

ローカルとプロダクションの違いや注意点

  • CRUD操作の権限は「ロールと権限」から付け直す必要がある
  • productionモードでは、コンテンツタイプの新規作成や削除はできない
  • よってコンテンツタイプの編集はローカルで行い、herokuにデプロイすることで反映させる必要がある
  • エントリーも作り直す必要がある

APIとして使用する場合

ローカルは「 http://localhost:1337/graphql 」で呼び出すことができます。herokuの場合は「 herokuアプリurl/graphql 」です。

複数のコンテンツタイプで一対多の関係性を持たせたい時

簡単なやること管理ツールを作ると仮定して「Project」と「Todo」というコンテンツタイプを作成しました。それぞれ「name」というフィールドを持たせています。

まず「Project has many todos」という関係性になるので、そのリレーションをはっていきます。

リレーションをはる

コンテンツタイプ作成から「Todo」、「Add another field」を選択します。Select a field for your content typeの画面で「Relation」を選択します。
Add new Relation fieldの画面で適したリレーションを選びます。今回の場合は「Project has many todos」ですね。「Finish」、「保存」を忘れずに。
image.png

リレーションをはったエントリーを作成する

左側のタブからTodosを選び、「Todoを追加」、nameを入力します。nameの横に「Project」と書いてあるボックスがあるので、そこで紐付けたいProjectを選択します。

image.png

TodoとProjectが取れるかどうかチェック

※ロールと権限から権限付与を忘れずに!

query getTodos {
  todos {
    id
    name
    project {
      id
      name
    }
  }
}

取れた!
image.png

すべてとれるか試してみる

今回は「status」というコンテンツタイプも作成しました。これは「todo has one status」というリレーションで紐づいています。

query getTodo {
  todos {
    id
    name
   status {
    id
  }
   project {
      id
    }
  }
}

取れた!
image.png

あるTodoのプロジェクトIDを変更してみる


mutation {
  updateTodo(input: {
    where: {
      id: 46
    },
    data: {
      name: "9時に起きる"
      project: 10
    }
  }) {
    todo {
      id
      name
      project {
        id
        name
      }
    }
  }
}

image.png

strapiをAPIとして使用しているアプリをvueで作っているので、axiosでgraphqlを使いたい方など、参考に見てみてください。
https://github.com/mtoyopet/vue-graphql-restaurant-list

mtoyopet
29歳でプログラマーになった人。Ruby/Rails・JavaScript/Vue/Nuxtネタが多め
https://note.mu/toyomomo
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away