LoginSignup
5
5

More than 3 years have passed since last update.

【Headless CMS】HerokuにStrapi入れてAPI叩く【無料】

Last updated at Posted at 2020-10-13

これまでバックエンドなしでReact使ったサイトを作ってきたけど,他の人も更新しやすいようにCMSを使った方がいいと思い実装してみた。

条件としては,半分趣味だし多分収益化しないだろうし全て無料であること。

StrapiというHeadless CMSを使いAPIをローカルで構築し,Herokuの無料アカウントにあげた上でフロントエンドからREST APIを使えるようになるまでを書いてみようと思う。

まずCMSとStrapiについて書きますが,既にある程度知っていましたらこちらまで飛ばしてください。そこから先は手順に沿って進めていきます。

目次

そもそもCMSって?
なんでSrapi?
参考にしたページ
ローカルでStrapi Appを作成する
Herokuにデプロイ
問題点とその解決法
まとめ

そもそもCMSって?

content management systemの略。代表的なモノで言うとWordPress。代表的というか,CMSシェア全体の63%を有しているからもはや代表。

WordPressには優れた点も欠点もあるけど,今回使うStrapiとの大きな違いはHeadlessであるか否か。WordPressはフロントエンドの仕組みも含んでおり,さらに大量のプラグインやテーマも使える巨大なシステムとなっている。それに対してStrapiはバックエンドのデータ管理のみを行い,フロントエンドは使う人に任せている。

Strapiと組み合わせやすいように様々なプラグインは用意されているけど,基本的にはフロントエンドがどんなでもREST APIやGraphQLでデータを取得できる。だから一度作ってしまえば,やりたければアプリやIoTデバイスへの拡張も簡単にできるそう。今回はそこまでやらないが,「必要だったらできる!」というのは今後の拡張考えると安心。

なんでSrapi?

まず無料。

Strapi によると,その長所はオープンソースであること,カスタマイズしやすいことなどなど。これらの点も含めて,個人的な魅力はめちゃくちゃ使いやすいこと。

ある程度コーディングに慣れていた方がカスタマイズはしやすいが,最低限必要なことはコマンドラインでnpx create-strapi-app と叩くだけ。あとは自動でサーバーが立ち上がり,そこに情報を入力していくだけOK。

また公式サイトのチュートリアルとドキュメントはすごく丁寧でよくあるシチュエーションをカバーしてるから,手順に従うだけで必要なカスタマイズは全てできた。なんならStrapi以外の要素も含んだチュートリアルもあるから,完全初心者から作りたいサイト公開までいけそう。

懸念点としては,結構新しいサービスだからネット上の情報は他のCMSに比べるとまだまだ少ない。特に公式は日本語へ対応していないため英語全く知らないと厳しいかも。でも,すごいことにStarpiそのものはある程度日本語に対応していて,アカウント作成やデータの追加をするときに英語で困ることはなさそう。そして日本での普及も進んでいるようで,Strapiとググれば公開一年以内の日本語の記事は一杯出てくる。

日本語で困ったことがあればこちらの記事も参考になるように書きますので,質問・要望あればお願いします!

参考にしたページ

今回は序盤のインストールはStrapiの公式ドキュメントを,その後のHerokuの使い方や問題点の解決法はPascal Couturierさんのブログを参考にさせていただいた。大まかな流れもこれらに準拠する。

Strapi 公式
Strapi Introduction

Pascal Couturierさんのブログ
Self Hosted Free Open Source CMS with Strapi.io

ローカルでStrapi Appを作成する

nodeのインストール

まずnodeをこちらからインストールして,npmnpx がコマンドラインから使えるようにする。

現在の私のnodeなどのバージョンはこちら。

$ node --version
v12.16.1
$ npm --version
6.14.8

Strapi appを作る

コマンドから以下を叩くと,./starpi-app に初期化されたStrapiのアプリができる。

$ npx create-strapi-app starpi-app --quickstart

strapi-app のところは任意のApp名。アプリを作ると同時にhttp://localhost:1337 にサーバーが立ち上がる。作成完了まで時間かかるが,以下の内容が表示されたら完了の合図。

To manage your project 🚀, go to the administration panel at:
http://localhost:1337/admin

To access the server ⚡️, go to:
http://localhost:1337

http://localhost:1337/admin にアクセスしてみよう。

ちなみに,間違えてサーバーを閉じてしまった場合は

$ cd ./starpi-app
$ npm run develop

で再開できる。

Strapi管理画面を表示

http://localhost:1337/admin にアクセスすると,初回は次のように自分の情報の入力画面が表示される。 

register

情報を入力したら以下の管理画面表示される。

admin

  • コレクションタイプ

    データベースの各テーブルにあたるメニュー。データベースのテーブルをstrapiでは「コンテンツ」,コラムを「フィールド」と呼ぶ。新しくコンテンツなどを作るとここに表示され,データを追加したり編集したりできる。

  • Content-Types Builder

    新しいコンテンツなどを作成する場所。ローカルの開発環境では使えるが,Herokuなどにあげるプロダクション版では新しいコンテンツの作成はできなくなるので,まず必要なコンテンツをローカルで作ってからHerokuにあげる。

  • 設定

    各種設置を行うメニュー。今回は「ロールと権限」の設定を行うが,他にメディアライブラリやメールテンプレートの設定などができる。

新しいコンテンツの作成

Content-Types Builderから公式のチュートリアルと同じようにrestaurantコンテンツを作成してみる。これは後ほど削除できるが,難しくないのでまず自分の必要そうなコンテンツをこれをもとに作成してみてください。

  • 「+ Create new collection type」をクリック

    add content

  • restaurant と入力し「続ける」を押す

    add content_restaurant

  • 「Text」フィールドを選択

    add content_text

  • Nameに name と入力

    add content_name

  • 「高度な設定」を選択し,「必須フィールド」と「一意のフィールド」を選択する

    add content_set

  • 下にスクロールし「+ Add another Field」をクリックし,「Rich Text」フィールドを選択

    add content_rich text

  • Nameに description と入力し「終了」をクリック

    add content_desc

  • 右上の保存ボタンを押し,サーバーがリスタートされるのを待つ。表示が再開されない場合はページを再読み込みするか,コマンドラインの表示を確認する。

    add content_save

成功すると,左のコレクションタイプに「・Restaurants」が追加されているはず。

試しにいくつかデータを追加してみましょう。

  • 右上から「+restaurantを追加」をクリック

    add restaurant1

  • 好きなレストラン名をNameに,その説明をDescriptionに書き右上から保存,そしてPublishする。(Publishしないと,表示はされるが外部からは基本表示されない状態になる)

    add restaurant2

テストのために同様の手順でいくつか作っておきましょう。

restaurants

APIの公開設定

デフォルトではAPIをリクエストすると拒否されるので,どこまで許可するかを設定する。

  • 左から「設定」>「ロールと権限」を選択すると,存在するロールの種類が表示される。デフォルトではログインしたメンバーが使えるAuthenticatedと誰でも使えるPublicの二つある。

    role1

  • Publicを選択し,「権限」から許可するAPIをチェックする。デフォルトでは全てオフになっているため,まずrestaurant数を表示するcount,全データ表示するfindとidを指定したものを表示するfindoneを許可して右上の「Save」ボタンをクリックする。

    role2

APIを試してみる

手早くAPIを試すには,http://localhost:1337/restaurants (restaurantを自分の設定したコンテンツ名に変える。)にアクセスしてみよう。

API test

権限設定がきちんとできていれば,上のようにrestaurantsのデータがjson形式で帰ってくる。もし

{"statusCode":403,"error":"Forbidden","message":"Forbidden"}

が帰ってきたら,権限がうまく設定できていない。もう一度設定を見直してみましょう。

詳しいAPIの送信・受け取り方法はフロントエンドの実装によるので説明しないが,Strapiではデフォルトで以下の6種類が使える。例えばrestaurantコンテンツの場合は{content-type}restaurants を当てはめて送ってみよう。現在の設定ではcountfindfindoneのみ許可してあるので,他のAPIを送ると拒否される。Publicに許可するのは危ないので,必要だったら先ほどの設定においてAuthenticatedを選択し許可したいアクションを設定しましょう。

アクション名 メソッド パス 説明
find GET /{content-type} {content-type}の全要素を取得
findone GET /{content-type}/:id {content-type}の:id番目の要素を取得
count GET /{content-type}/count {content-type}の要素数を取得
create POST /{content-type} {content-type}の新要素を作成
delate DELETE /{content-type}/:id {content-type}の:id番目の要素を削除
update PUT /{content-type}/:id {content-type}の:id番目の要素を更新

ちなみに,Postmanというアプリが使いやすくAPIのテストに役立つのでお勧めです。もちろん無料。

Download Postman | Try Postman for Free

Herokuにデプロイ

Herokuでは少なくとも1サーバーは無料で使える。機能はもちろん限られるが,十分すぎるぐらい高機能な上,他の無料サービスを組み合わせれば足りない点もある程度補える。

Herokuに作ったStrapi Appをあげてみよう。細かい設定は公式の以下のドキュメントを参考にし,データベースはPostgreSQLを用いた。

Strapi Heroku

gitがない場合は,あらかじめインストールしておこう。

git インストール

注意
コンテンツの各要素はデータベースに入っているため反映されません。必要だったら新しく作り直すか,後ほどlocalのデータをAPI使ってHerokuで再作成しましょう。または外部のデータベースを使えばローカルとプロダクションで同じデータを使えます。

デプロイ先では新しいコンテンツの作成ができなくなります。必要だったらHerokuにあげる前に他のコンテンツを作っておきましょう。

Heroku CLIダウンロード

まずHeroku CLI をそれぞれのOSに合わせてダウンロードする。

Mac :

https://cli-assets.heroku.com/heroku.pkg またはHomebrewを使って

$ brew tap heroku/brew && brew install heroku

Windows :

64-bit https://cli-assets.heroku.com/heroku-x64.exe
32-bit https://cli-assets.heroku.com/heroku-x86.exe

Ubuntu :

$ sudo snap install --classic heroku

Herokuにログイン

コマンドで

$ cd ./strapi-app #strapi app内に移動しておく
$ heroku login

と打つとログインフォームが立ち上がる。アカウントがない場合はこちらから作ることもできる。

スクリーンショット 2020-10-12 18.47.22.png

この画面が表示されたらコマンドに戻る。

.gitignoreファイルを更新

.gitignore ファイルに以下の一行を追加する。

package-lock.json

Herokuではyarnを使っている影響でpackage-lock.jsonを追加するとエラーが出るらしい。

ドキュメントにはないが,yarnを以下で起動しyarn.lock を更新しておく方がいいかも。(自分の場合はこれをしなかったときエラーを出したため)

$ yarn install

gitをinitする

gitを作りコミットする。

$ git init
$ git add .
$ git commit -m "Initial Commit"

Herokuに新プロジェクトを作成

$ heroku create strapi-app

strapi-app には好きなプロジェクト名を当てはめる。何も入力しなければ自動で適当な名前が付けられる。

Herokuにデータベースを作成

PostgreSQLのデータベースを作成する。

  1. コマンドからHerokuのPostgresアドオンをいれる

    $ heroku addons:create heroku-postgresql:hobby-dev
    
  2. データベースの情報を確認

    $ heroku config
    

    DATABASE_URL: postgres://ebitxebvixeeqd:dc59b16dedb3a1eef84d4999sb4baf@ec2-50-37-231-192.compute-2.amazonaws.com: 5432/d516fp1u21ph7b のような内容が表示されればデータベースの立ち上げは完了。

  3. 必要なPostgresパッケージを追加

    $ yarn add pg pg-connection-string
    

    または

    $ npm install pg pg-connection-string --save
    
  4. データベース設定ファイルを作成

    config フォルダに新しいディレクトリenv/productionを作り,以下の内容でdatabase.js をそこに追加する。

    const parse = require('pg-connection-string').parse;
    const config = parse(process.env.DATABASE_URL);
    
    module.exports = ({ env }) => ({
      defaultConnection: 'default',
      connections: {
        default: {
          connector: 'bookshelf',
          settings: {
            client: 'postgres',
            host: config.host,
            port: config.port,
            database: config.database,
            username: config.user,
            password: config.password,
          },
          options: {
            ssl: false,
          },
        },
      },
    });
    

変更をコミットし,Herokuにデプロイする

$ git add .
$ git commit -m "Update database config"
$ git push heroku master

これでHerokuにデプロイが開始する。結構時間がかかるが,うまくいくと以下のような内容が表示される。

remote: -----> Launching...
remote:        Released v6
remote:        https://strapi-app.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy... done.
To https://git.heroku.com/strapi-app.git
   45a0a5a..e43g2ef  master -> master

上記のhttps://strapi-app.herokuapp.com 該当部分にアクセスした時に以下の画面が表示されたら完了!

スクリーンショット 2020-10-12 19.50.21.png

できない場合は,Herokuのログを以下を使い確認してみてください。

$ heroku logs --tail

デプロイ版の管理画面を表示

http://strapi-app.herokuapp.com/adminstrapi-app を自分のアプリ名に変更)にアクセスすると,再度ユーザー登録が求められる。

データベースに保存されたコンテンツの各要素と設定は反映されない。まずログインしたら「ロールと権限」を設定してからAPIを使って再度追加したりしよう。

問題点とその解決法

以上でHerokuにStrapiを使ったアプリの立ち上げは終わった。ただ,このままではいくつかの点で実際に運用するには問題がある。

HTTPSに対応できない

Herokuは有料サーバーなら無料でSSLが使え,HTTPS接続に対応できるようになる。逆にいうと,どんなに頑張っても完全無料でHTTPS接続することは不可能らしい。

APIのテストをするだけなら問題ないと思っていたためこの点は最初は気にしていなかったが,どうもフロントエンド側からAPIを叩くときにhttpsじゃないと勝手にブロックされるらしい。安心。

どう解決するかというと,Cloudflareというサービスを使う。

これは簡単にいうと,Herokuとフロントエンドの間に入り,ブラウザとサーバーとの通信をセキュアにするサービスである。他にもいろいろ設定できるが,今回はSSL/TLS設定を目的に使用する。

cloudflare
Cloudflare.comから引用

細かい設定方法は英語になるがこちら

概要としては,

  1. ドメインを取得する

    お名前.comを用いるのが楽ではあるが,無料のドメインも探せばある。http://www.freenom.comとかなら少なくとも1年間無料でドメインを取得できる。

    例として,example.com というドメインを取得したとして以下進める。

  2. Herokuにドメインを追加

    $ heroku domains:add example.com
    

    追加が完了したら,後ほど使うDNS Target(以下のwhispering-willow-5678.herokudns.com 該当部)を取得しておく。

    $ heroku domains
    === strapi-app Heroku Domain
    strapi-app.herokuapp.com
    
    === strapi-app Custom Domains
    Domain Name      DNS Record Type DNS Target                                             
    example.com ALIAS or ANAME  whispering-willow-5678.herokudns.com
    
  3. Cloudflareに登録し,取得したドメインを追加する

    Cloudflareの登録はこちらから

    登録する過程でドメインの追加といくつか設定を行う。この時点で4.の設定を行ってもいい。

    nameserversの設定はドメインを取得したサイトごとに異なる。freenom.comならhttps://my.freenom.com/clientarea.php?action=domainsから該当するドメインについて以下のように選択していくと設定画面に行ける。

    「Manage Domain」>「Management Tools」>「Nameservers」

    nameservers

  4. CloudflareのDNSを以下のように設定する

    dns

    TypeはCNAMEを選択,Nameはサブドメインがない(wwwとかついていない場合を設定する)ときは@,そしてIPv4 addressに2.で取得したDNS Targetを設定しセーブする。

  5. しばらく(最大で1日)待つとCloudflareから使えるようになったとの連絡がメールで届くはず。

設定が完了するとhttp://strapi-app.herokuapp.com の代わりにhttps://example.comからstrapi appにHTTPSで接続できるようになる。

もちろんですが,これでセキュリティが万全になるといったものではないです。さらに追加の設定も可能なので,公式のドキュメントの確認をお願い致します。
https://help.heroku.com/GVS2BTB5/why-am-i-getting-error-525-ssl-handshake-failed-with-cloudflare-when-using-a-herokudns-com-endpoint

写真を保存できない

Strapiにはメディアライブラリという写真などのファイルを管理する機能がある。だが,Herokuの無料サーバーはエフェメラルファイルシステムといってリスタートされるたびにストレージが消えるという特性があるため,メディアライブラリに保存されたものはサーバーがスリープするたびに消えてしまう。

その対応として,外部のメディア管理サービスにつなげる。今回はCloudinaryを使ってみた。

公式だとAWSのS3を使っているが,手順としては同じである。

Strapi Upload Documentation

  1. Providerをインストールする

    $ yarn add strapi-provider-upload-cloudinary
    

    または

    $ npm install strapi-provider-upload-cloudinary --save
    
  2. Cloudinaryに登録しアカウント情報を取得する。

    Cloudinaryへの登録はこちら

    登録完了すると以下のDashboardが表示される。

    Cloudinary

    こちらからCloud name,API KeyとAPI Secretの三つを後ほど使う。

  3. Scrapi App内に.env ファイルを作成し,先ほど取得した情報を設定する。

    CLOUDINARY_NAME="Cloud name"
    CLOUDINARY_KEY="API Key"
    CLOUDINARY_SECRET="API Secret"
    

    それぞれ2.で取得した値を入力し保存し,config 内にplugins.js を以下の内容で作成する。

    module.exports = ({ env }) => ({
      upload: {
        provider: 'cloudinary',
        providerOptions: {
          cloud_name: env('CLOUDINARY_NAME'),
          api_key: env('CLOUDINARY_KEY'),
          api_secret: env('CLOUDINARY_SECRET'),
        },
      },
    });
    

    もしCloudinaryをHerokuのみで用いてローカルでは使わない場合は,これらの情報をHerokuに直接登録することもできる。

    $ heroku config:set CLOUDINARY_NAME="Cloud name"\
    CLOUDINARY_KEY="API Key"\
    CLOUDINARY_SECRET="API Secret"
    

    その上で,先ほど設定したconfig/plugins.jsconfig/env/production/ に移動する。.env ファイルは削除しておく。

  4. Herokuを更新する。

    $ yarn install
    $ git add .
    $ git commit -m "Update upload plugins"
    $ git push heroku master
    

完了!

管理画面の「メディアライブラリ」から写真をアップロードすると,Cloudinaryにアップロードされる。ストレージと通信量には制限があるが,無料プランでもしばらくは大丈夫そう。

media library

まとめ

バックエンドでAPI作って使うのは,まずサーバーがお金かかるしバックエンドって難しいしで諦めていた。その分フロントエンド側を工夫して似たようなことをできないか試してきた。

今回Strapiを使って作ってみたがめちゃくちゃ使いやすいので,他の用途にもいろいろ試してみようと思う。またメインのプロダクトはReactで作っているので,GatsbyといったStrapiとの相性がいいサービスも使ってみたい。

Strapi Gatsby Documentation

セキュリティの点などはまだまだ中途半端な気がするので,アドバイスあればお願いします!無料の範囲内でどこまでできるか試していきたいです。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5