Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って始めたブログ

【strapi】HeadlessCMSのstrapiを触ってみた

前回の記事では、HeadlessCMSの概要について書きました。

kodak.hatenablog.com

今回はHeadlessCMSのstrapiを触ってみた記事を書いていきます。

strapiとは?

APIを簡単に作成できるオープンソースのHeadlessCMSです。
まだアルファ版ようですが、完成度が非常に高く、GUIAPIを簡単に作ることができます。
ちなみにstrapiは、Node.jsで作られています。

strapi.io

私が動作確認した時のバージョンは以下の通りです。

  • Strapi 3.0.0-alpha.24.1
  • Node 10.3.0
  • npm 6.4.1

インストール

まずは、以下手順にそってStrapiのインストールとプロジェクトの作成を行います。

Quick Start Guide | Strapi Documentation

npm install strapi@alpha -g
strapi new cms --quickstart

quickstartオプションをつけると、データベースはSQLite3が自動で選択されます。
quickstartオプションをつけずにコマンドを実行して、Customを選ぶとデータベースはSQLite3、MongoDB、MySQL、Postgresから選択できます。
ちなみに、strapiはMongoDBを押しているようです。

APIを作る

ユーザー登録をして、管理画面に入るとAPIを直接作ることができます。
コンテンツタイプ作成からコンテンツタイプの名前を決めて、フィールドを選びます。
注)コンテンツタイプの名前は必ず単数形にしてください。(コンテンツタイプの名前はAPIの名前にもなります。APIは自動で複数形になります。)

f:id:special-moucom:20190503235759p:plain

APIの公開範囲を設定

上記でAPIの作成は完了しています。自動で以下APIが作成されています。

  • count ・・・ コンテンツタイプのデータをカウント
  • create ・・・ コンテンツタイプにデータ追加
  • destroy ・・・ コンテンツタイプからデータを削除
  • find ・・・ コンテンツタイプ内のデータ検索
  • findone ・・・ コンテンツタイプ内のデータ検索(id検索)
  • update ・・・ コンテンツタイプ内のデータ更新

しかし、APIはデフォルトでは未公開の状態になっています。
ロールと権限から(とりあえず)Publicを選択して、自動で作られたAPIの公開範囲を設定します。

f:id:special-moucom:20190503235905p:plain

APIを実行してみる

APIcurlコマンドや、ブラウザから直接URLを叩いてみます。
こんなに簡単にAPIが作られるなんて、衝撃ですよね!!

f:id:special-moucom:20190503235925p:plain

どのような仕組みでAPIが実装しているのか?

では、この自動生成されたAPIはどのようにして実装されているのか、少し深掘りしてみます。strapiのプロジェクト内では以下のようなディレクトリ構成でAPIが作られていることがわかります。(MVCモデルを採用しているようです。)また、strapiのマニュアルを読むと改良時にコードを書くべき場所も指定されていました。

f:id:special-moucom:20190503235942p:plain

少し改良を加えてみる

お題:

コンテンツタイプGoogleuserコンテンツタイプのuidには、重複可能なデータを入力することができてしまう。これを重複できないようにしたい。

回答:

■controllers(変更)

  create: async (ctx) => {
    // 自動生成されたコードはコメントアウト
    // return strapi.services.googleuser.add(ctx.request.body);
    // 登録するuidをカウントしてデータがあるかを確認する。カウント結果が0以外は400エラーを発生させる 。
    if ( await strapi.services.googleuser.uidcount(ctx.request.body) !== 0 ) {
      return ctx.response.badRequest('invalid query');
    }
    return strapi.services.googleuser.add(ctx.request.body);
  },

■services(追加)

  uidcount: async (values) => {
    // query関数を呼び、where句を指定してcount関数を呼び出す
    return Googleuser.query(function(qb){
      qb.where('uid', '=', values.uid );
    }).count();
  },

実行結果:

uid : test-uidのデータを追加するとエラーコード400を返す

$ curl -X POST -H "Content-Type: application/json" -d '{"uid":"test-uid"}' localhost:1337/googleusers
{"statusCode":400,"error":"Bad Request","message":"invalid query"}$

uid : test3(未登録)のデータを追加する登録したコンテンツタイプのデータを返す

$ curl -X POST -H "Content-Type: application/json" -d '{"uid":"test3"}' localhost:1337/googleusers
{"id":23,"uid":"test3","created_at":1556893121297,"updated_at":1556893121297}$

こんな感じでcontrollersとservicesに改良を加えていけば、APIに改良を加えたり、新しいAPIも作ることができそうです。

感想

strapiの完成度の高さに驚きました。なによりGUIで簡単にAPIが作れるのに凄く驚きました。Node.jsで作られているので相性が良いFirebaseと組み合わせて作ると面白そうです。
他にも説明しきれていない機能もたくさんあるので、ちょいちょい見つけたらまた記事にしたいと思います。