とよももです!
お仕事で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を触っていきたいと思います。
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 にアクセスします。
ローカルサーバを動かすコマンド
万が一ローカルサーバを止めてしまったら下記のコマンドで動かしてください。
$ npm run develop
コンテンツタイプの作成
いきなりコンテンツタイプ
と出てきて混乱してしまいますが、通常のデータベース
の
-
コンテンツタイプ
→ テーブル名 -
フィールド
→ カラム名 -
エントリー
→ レコード
だと思って進めるとわかり易いです。
初めてのコンテンツタイプを作成
まずは「テーブル名」となるコンテンツタイプ
を作成していきます。
本記事では、「Restaurant」というコンテンツタイプ
を作成します。また、「name」と「description」という2つのフィールド
を作成します。
左側のタブから「Content Types Builder→「Create new collection type」を選択します。
Display Nameを入力し、「続ける」を押下します。ちなみに、Display Nameは単数形で問題ありません。Strapiが自動で複数形に直してくれます。
content typeフィールドを選択し、名前を入力し「Finish」を選択します。今回は「text」タイプの「name」というフィールドを作成しています。
最後に、画面右側に詳細が表示されるので、保存ボタンで上書きしましょう。
エントリーを作成
次に、レコードとなるエントリー
を作成していきます。左側のタブからRestaurantsを選択し「Restaurantを追加」ボタンを選択します。
レストラン名と詳細を入力し保存すると、レコード
が作成されます。
レコードが作成されたあと、右上の「Publish」ボタンをクリックします。
権限の設定
CRUD操作を行うには、別途権限を付与する必要があります。設定を行ってない場合は、APIを呼び出しても404エラーになってしまうのでこの設定は忘れない様にしてください。
左側のタブから「設定」を選び、「ロールと権限」→「Public」を選択します。Restaurantの「findone」にチェックをいれるとレストランを1つだけ呼び出すためのAPIのURLが右側に表示されます。あとで「create」「update」「delete」もやるので、全てにチェックを入れておきましょう。右上の「save」ボタンを忘れずにクリックします。
保存をして、 試しに localhost:1337/restaurants/1 にアクセスしてみます。
取れた!
GraphQLを使ってCRUD操作を行う
プラグインを導入
GraphQLはデフォルトで入っていないため、プラグインとして別途導入する必要があります。
$ strapi install graphql
// ↑でインストール後エラーが出る場合、
// $ strapi uninstall graphql コマンドでアンインストールし、
// ↓のコマンドで試してみてください
//または
$ npm run strapi install graphql
//または
$ yarn strapi install graphql
導入が完了したら、 http://localhost:1337/graphql にアクセスします。
こんな画面が出てくるはず!ここでGraphQLをいじってデータを取ったり新規作成したりできます。
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
}
}
CREATE: Restaurantを新規作成する
mutation {
createRestaurant(input: {
data: {
name: "みっちゃん",
description: "広島で有名なお好み焼き屋さん"
}
}) {
restaurant {
name
description
}
}
}
DELETE:Restaurantを削除する
mutation {
deleteRestaurant(input: {
where: {
id: 3
}
}) {
restaurant {
name
description
}
}
}
UPDATE:Restaurantを編集する
mutation {
updateRestaurant(input: {
where: {
id: 26
},
data: {
name: "モスバーガー"
}
}) {
restaurant {
name
}
}
}
Herokuにデプロイする
デプロイの準備
StrapiをHerokuにデプロイする方法です。詳しくは「公式サイト」にめちゃくちゃ丁寧な解説が載っています。詳しく知りたい方は公式ページを読みながら進めることを強くお勧めします。
デプロイの前に下記を行ってください。
・Gitをインストール
・Herokuアカウントの新規作成
・Heroku CLIのインストール
Gitを有効化、最初のcommitをしておきます。
$ cd my-app
$ git init
$ git add .
$ git commit -am "Initial commit"
Herokuアプリを新規作成します。
$ heroku create
この時点で、自身のHerokuアカウントを覗くと、アプリが作成されているはずです。
Postgresのアドオンを追加する
ローカルではsqliteを使用していましたが、Herokuでは今回はPostgresqlを使っていきます。HerokuのアドオンにPostgresを追加します。
$ heroku addons:create heroku-postgresql:hobby-dev
環境変数を設定する
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
⬆️のデータベースは既に削除してます。本来であれば機密情報なので、⬆️のように大衆が見る場所にデータベース情報を晒さないよう、十分注意してください。
database configファイルの修正
./config/environments/production/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
「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」、「保存」を忘れずに。
リレーションをはったエントリーを作成する
左側のタブからTodosを選び、「Todoを追加」、nameを入力します。nameの横に「Project」と書いてあるボックスがあるので、そこで紐付けたいProjectを選択します。
TodoとProjectが取れるかどうかチェック
※ロールと権限から権限付与を忘れずに!
query getTodos {
todos {
id
name
project {
id
name
}
}
}
すべてとれるか試してみる
今回は「status」というコンテンツタイプも作成しました。これは「todo has one status」というリレーションで紐づいています。
query getTodo {
todos {
id
name
status {
id
}
project {
id
}
}
}
あるTodoのプロジェクトIDを変更してみる
mutation {
updateTodo(input: {
where: {
id: 46
},
data: {
name: "9時に起きる"
project: 10
}
}) {
todo {
id
name
project {
id
name
}
}
}
}
strapiをAPIとして使用しているアプリをvueで作っているので、axiosでgraphqlを使いたい方など、参考に見てみてください。
https://github.com/mtoyopet/vue-graphql-restaurant-list