strapiでブログを作る③(バックエンド)

strapiのバックエンド部分の作り方について説明します。

Programming
Kuriya Ushiki
Kuriya Ushiki
投稿日 5/20/2024
更新日 5/20/2024

バックエンドといっても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の権限変更できる画面が出てくるのでよしなに変更します。 スクリーンショット 2024-05-17 9.58.10.png 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としています。 スクリーンショット 2024-05-18 11.35.08.png

次にfieldを選びます。

  • name - 表示されるtext
  • slug - urlなどで使われるtext
  • articles - tagと関連している記事
  • description - tagの説明

スクリーンショット 2024-05-18 11.34.25.png

ここで重要なのが、articlesの部分です。

tagはarticleと多対多(many to many)で紐づくので以下を選択します。

スクリーンショット 2024-05-18 11.33.49.png

以上でtagsの設定はOKです。 これで自動でDBもスキーマファイルも作られます。

参考 https://beamaker.jp/article/10

S3の導入

※ 当ブログでは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に保存されるようになる。

参考

動画

ざっと流れを把握するのに良さそうなYoutubeの動画を見つけたので、紹介しておきます。 <iframe width="560" height="315" src="https://www.youtube.com/embed/gSwSKEDGPkQ?si=aP1lxIbkJq0T_NXc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

まとめ

以上がstrapiバックエンドの作り方になります。 今回はdockerやminioを導入しましたが、実際には不要だったと感じています。 すぐに本番環境を作り、開発する際は本番のDBやS3に繋いだlocal環境から開発するのが良さそうでした。

良かった点

  • カスタマイズ性がある
  • 管理画面がシンプル
  • プラグインが豊富
  • 権限管理も充実している

悪かった点

  • 公開日や更新日や作成日が編集できない
  • rich textのエディターで文章を打っているとたまに前の文章が出てくるみたいなバグっぽい挙動がある
  • 下書き保存がない。(strapi5から追加されるらしい)
  • APIの返り値に無駄なdataとattributesという階層がある
  • markdownで改行の際に2つスペースを入れなくてはならない。