strapiでブログを作る③(バックエンド
strapiのバックエンド部分の作り方について説明します。
バックエンドといってもapiだけでなく管理画面の部分も含まれます。
strapiのプロジェクトを作成
まずはこちらのドキュメントを踏まえたうえで Installing from CLI
npx create-strapi-app@latest protagram --template blog
こちらのコマンドを実行します。 ※protagramというのはプロジェクト名となるので任意のものに変更してください。
私が選んだ選択肢は以下となります。
? What would you like to name your project? protagram
? Choose your installation type Custom (manual settings)
? Choose your preferred language TypeScript
? Choose your default database client postgres
? Database name: protagram
? Host: 127.0.0.1
? Port: 5432
? Username: postgres
? Password: ********
? Enable SSL connection: No
留置すべきはinstallation typeをcustomにしてtypescriptを選択してDBにpostgresを選んだことぐらいです。
みそとしては--template blog
をつけているあたりです。
strapi - templates
これをつけることで、blogに必要なContent-Typeのスキーマファイルなども事前に作ってくれます。
一つ問題点としてはtypescriptを選択した場合作られたスキーマのファイルなどはjsファイルなどでtsに書き換えないとバグになります。後で紹介する権限を変更する画面に追加さているはずのcontentが表示されない事象がおきてしまいます。なので事前に修正しておくことをおすすめします。
graphqlのプラグインをインストール
後でgraphqlを試してみるので、その時に使うgraphqlのプラグインを事前にインストールしておきます。 https://docs.strapi.io/dev-docs/plugins/graphql
npm run strapi install graphql
Dockerの作成
dockerを使ってlocalで立ち上げられるようにします。 ただ実際に使っていくときはほとんどdockerを立ち上げなくなりました。 というのも本番環境を作ったら、localでも本番DBに接続して編集するような運用になったからです。 それでも一応説明しておきます。 まずはドキュメント Running Strapi in a Docker container
今回はドキュメントでも紹介されていた@strapi-community/dockerize
を使います。
npx @strapi-community/dockerize
You, and 504 other people have used this tool this month
🍿 TypeScript project detected
✔ Yarn not installed! Shall we install it for you? (Strapi Recommended) … No / Yes
📦 Using NPM
🚀 Strapi 4.19.0 detected
✔ Do you want to create a docker-compose file? 🐳 … No / Yes
✔ What environments do you want to configure? › Both
✔ Whats the name of the project? … protagram
✔ What database do you want to use? › PostgreSQL
✔ Database Host … localhost
✔ Database Name … protagram
✔ Database Username … protagram
✔ Database Password … *********
✔ Database Port … 5432
🐳 Checking for existing Docker files...
🐳 Found: .dockerignore, Dockerfile in project directory.
🪄 Moving .dockerignore to backup directory...
🪄 Moving Dockerfile to backup directory...
📦 Backed up .dockerignore, Dockerfile
🐳 Added docker-compose file with POSTGRESQL configuration
🕵️ Updated Dockerize variables in .env
💾 Added POSTGRESQL configuration to database.ts
📦 No old dependencies to clean up
後は立ち上げるだけ
docker-compose up -d strapiDB && npm run develop
参考サイト ローカルにheadless CMSを立てる
日本語化
./src/admin/app.example.tsxのファイルをcopyして./src/admin/app.tsxに変更
export default {
config: {
locales: ["ja"], // <=ここをついか
},
bootstrap(app) {
console.log(app);
},
};
反映させるにはnpm run build
をする必要がある。
graphqlのplaygroundでデータが取得できるかテスト
↑でnpm run developしているのでlocalhostで管理画面にアクセスできます。 graphqlのプラグインも入れているので以下にもアクセスできるはずです。 http://localhost:1337/graphql
まずは何かデータを作る。
blog テンプレートを使っているならすでにarticleとかcategoryが存在するはず。
項目が少ないのでcategoryを取得しようとすると以下のようになる。
query{
categories{
data{
attributes{
name
}
}
}
}
しかしこのまま実行してもForbidden accessとなって取得できない。
APiトークンを作ってアクセスする方法
管理画面のAPIトークンからトークンを発行する。 graphqlのplayground画面の左下にhttp headersというタブがあるのでクリックして以下を追加
{ "Authorization": "Bearer <token>" }
これを追加した後、再度実行すれば取得できるはず。
各Content-Typeの権限を変更してアクセスする方法
多分こちらの方が一般的。 左サイドメニューより「Settings」を選択し、「USERS&PERMISSIONS PLUGIN」欄の「Roles」をクリックします。「NAME」が「Public」のレコードをクリックします。 すると以下のような感じで存在するContentの権限変更できる画面が出てくるのでよしなに変更します。
publicはエンドユーザーに対しての権限となるのでブログの場合は全ての項目でfindとfindOneだけ追加しておけばよいと思います。 コメント機能をつけたい時などだけcreate,delete,updateの権限を付与する形になるかと思います。
権限管理画面に存在してるcontent-typeが存在しない場合
原因はnpx create-strapi-app@latest protagram --template blog
で追加した際に--template blog
で追加されたapi/
以下のファイルがtsではなくjsだったため、こちらtsに変更したところ表示されるようになった。
参考 https://n-laboratory.jp/articles/strapi-api
APIで取得する階層の制御
strapi-plugin-populate-deep
デフォルトだとAPIで取得できるデータが1階層までしかない。 其のためリレーションのあるデータなどは取得することができない。 それをプラグインを使うことで解消できる。
npm install strapi-plugin-populate-deep
npm strapi-plugin-populate-deep こちらをインストールすることで全部の階層まだ取得できるようになった。
本当はgraphQLとかで必要なデータだけ随時取ってくるようにしたほうがいいかも
strapi-plugin-transformer
例えばcategoryのnameを取得したいだけでも category.data.attributes.nameって形返ってくるのですがこのdataとattributesの階層不要だと感じることが多々ある。 そこで使いたいのがstrapi-plugin-transformer 実際まだ使ってないがこれをインストールするとdataとattributesのネストが消えるらしい。 プラグインを使わない方法もあるようです。 https://cookin.dev/website/1452/
tagの追加
blogのテンプレートを使ってもtagのcontentは追加されていなかった。 なので自分で追加する。
Content-Type Builderを選択してcreate new collection typeをクリックします。 すると以下のモーダルが出るのでtagと入力します。 ※私はすでにtagが存在していたのでtag2としています。
次にfieldを選びます。
- name - 表示されるtext
- slug - urlなどで使われるtext
- articles - tagと関連している記事
- description - tagの説明
ここで重要なのが、articlesの部分です。
tagはarticleと多対多(many to many)で紐づくので以下を選択します。
以上でtagsの設定はOKです。 これで自動でDBもスキーマファイルも作られます。
参考 https://beamaker.jp/article/10
S3を使うことを想定してローカルにminioを導入
※ 当ブログではS3を使うのをやめてcloudflare r2を使うことにしたので参考までに気になる方は読んでください。
provider-upload-aws-s3をインストールする。
npm install @strapi/provider-upload-aws-s3 --save
/config/middlewares.tsの修正
export default ({ env }) => [
{
name: "strapi::security",
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
"connect-src": ["'self'", "https:"],
"img-src": ["'self'", "data:", "blob:", 'market-assets.strapi.io', `${env("AWS_PRIVATE_ENDPOINT")}`],
"media-src": ["'self'", "data:", "blob:", 'market-assets.strapi.io', `${env("AWS_PRIVATE_ENDPOINT")}`],
upgradeInsecureRequests: null,
},
},
},
},
....
];
minioを追加するためにdoker-compose.yamlに以下を追加
protagramMinio:
container_name: protagramMinio
image: minio/minio:latest
ports:
- 9000:9000
- 9001:9001
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
MINIO_ACCESS_KEY: ${AWS_ACCESS_KEY_ID}
MINIO_SECRET_KEY: ${AWS_SECRET_ACCESS_KEY}
command: server --address 0.0.0.0:9000 --console-address :9001 /data
volumes:
- "protagram-minio:/data"
networks:
- protagram
healthcheck:
test: ["CMD", "curl", "-f", "<http://localhost:9000/minio/health/live>"]
retries: 3
timeout: 5s
volumes:
protagram-data:
protagram-minio:
networks:
protagram:
name: Protagram
driver: bridge
.envの内容
FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=access
AWS_SECRET_ACCESS_KEY=secret
AWS_REGION=us-east-1
AWS_BUCKET=protagram
AWS_USE_PATH_STYLE_ENDPOINT=true
AWS_PRIVATE_ENDPOINT=http://localhost:9000
AWS_PUBLIC_ENDPOINT=http://localhost:9000/protagram
これでminioにprotagramというbucketを作って権限をpublicにすればアップロードした画像などがminioに保存されるようになる。
参考
- Configure MINIO as Strapi media storage
- How to Set up Amazon S3 Upload Provider Plugin for Your Strapi App
- Strapi V4をHerokuとS3にデプロイし、安くて自由なHeadlessCMS環境を手に入れる。
トラブル時の対処法
メディアライブラリをクリックした際に画面が真っ白になった際の修正方法
dockerを消す。DBの消えるので気をつけてください
docker-compose down --rmi all --volumes --remove-orphans
管理画面のcontent managerのCOLLECTION TYPES選択した際に画面が真っ白になる
consoleをチェックすると以下のエラー文が出ていた。
main.71af1bb6.js:621 TypeError: Cannot destructure property 'params' of '(0 , he.W5)(...)' as it is null. strapi
.strapi, dist, node_modules, package-lock.jsonを削除して
npm install
npm run build
npm run develop
これで治った。
動画
ざっと流れを把握するのに良さそうなYoutubeの動画を見つけたので、紹介しておきます。
まとめ
以上がstrapiバックエンドの作り方になります。 今回はdockerやminioを導入しましたが、実際には不要だったと感じています。 すぐに本番環境を作り、開発する際は本番のDBやS3に繋いだlocal環境から開発するのが良さそうでした。
良かった点
- カスタマイズ性がある
- 管理画面がシンプル
- プラグインが豊富
- 権限管理も充実している
悪かった点
- 公開日や更新日や作成日が編集できない
- rich textのエディターで文章を打っているとたまに前の文章が出てくるみたいなバグっぽい挙動がある
- 下書き保存がない。(strapi5から追加されるらしい)
- APIの返り値に無駄なdataとattributesという階層がある
- markdownで改行の際に2つスペースを入れなくてはならない。