フレームワークを使わずにヘッドレスCMS(microCMS)を作ってみた※Vue.js利用

Vue.jsを勉強していると、自然と使う機会が多くなるAPI。
フレームワークとしてVue CLIを使ったりNuxt.jsを使うことが多いかと思いますが、費用対効果がある大規模案件に巡り会える機会は、なかなかありません。

そんな中で、最近話題のヘッドレスCMS。
- データベース不要
- PHP不要
- サーバーが別なのでセキュリティが高い
- 定期的にアップデートする必要がない

といったメリットがあり、
元Wordpress専門会社で働いていた私にとって、画期的な内容となっています。

しかし、ヘッドレスCMSで推奨されている使い方通りにやろうとすると、
フレームワークなどの前提とする知識が多すぎて、
初心者にハードルが高い印象になります。

しかし、APIの使い方を調べていくと
**下層ページが必要ないLP案件を作る想定**なら、
Wordpressよりも気軽に実装出来るのでは思いました。

そこで私は、フレームワークを使わずに実装してみましたので、
その内容をまとめさせていただきます。

# 前提・想定依頼内容
- 「すでにあるLPにお知らせを投稿出来るようにしたい」といったご要望を想定する
- 下層ページを作る予定はない

# 基本仕様
- ヘッドレスCMSはmicroCMSを利用
エディタがWordpressのクラッシクエディタと似ている印象を受けました
- HTMLはindex.htmlのみ
- CDNとして実装
    - Vue.js@2.6.14
    - axios
   
※実際のサイトではSCSSとjQuery、jQueryプラグインも利用しました。

## Vue.jsを使う理由

素のJavascriptのみで書くことが出来ますが、
- v-if、v-forを使えば、Wordpressに似たような感覚で作れるため
- 変数とHTMLを混同させたくないため
- 他の案件で使う時、Javascriptに手を加えずに反映出来る範囲を増やしたい
- ブラウザの機能を使うfetchよりも、ライブラリのaxiosの方が信頼出来るため(個人的見解)

という理由から、私はVue.jsを利用させていただきます。

Vue.jsが触ったことがない人は、「基礎から学ぶVue.js」というネコの本を読みながら、一通りやってみるといいと思います。

https://www.amazon.co.jp/%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6-Vue-js-MIO-ebook/dp/B07D9BYHMZ

この本はCDNを利用してVue.jsを動かすことを前提として書かれているので、最小限の学習内容でVue.jsを学べます。
なお、後半のVueCLIの前の章まででOKです。

## 必要なスキルレベル

個人的な体感としては、

- **Worpdressのカスタムフィールドを使って構築出来る**くらいのスキルのある人
- ネコの本の内容についていける人
- 何かしらのAPIを使ったことがある人

なら、1サイト作っただけで、大体要領がつかめる感じだと思います。

ちなみに、私が躓いたところはこちらになります。
https://qiita.com/ayaoriko/items/339df665eb831b123143

## STEP2：microCMSの管理画面側の設定

microCMSのアカウントを作り、APIの基本情報を入力します。
ちなみに、microCMSでは無料で3つまで登録出来ます。

![スクリーンショット 2022-10-07 16.35.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225361/3b21b0f9-acac-ec80-3d01-cf04d2561b69.png)

リスト形式を選択して、

![スクリーンショット 2022-10-07 16.40.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225361/bc7273a8-dfbc-e556-ca93-ecab27fd2a9a.png)

APIスキーマを定義(つまり入力枠を設定)します。
![スクリーンショット 2022-10-07 16.50.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225361/7fc4d2d5-d3d3-76d4-565f-a2f7a4f4303c.png)

右上の「追加」ボタンを押していくつかコンテンツを入力します。
![スクリーンショット 2022-10-07 16.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225361/415fa4cd-764e-93a1-b296-158ea316ad07.png)

## STEP2：microCMSのAPIキーを確認する
microCMSでAPIを呼び出すには、APIキーを設定する必要があります。
左下の「x個のAPIキー」というところから、APIキーを確認できます。
![スクリーンショット 2022-10-07 17.01.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225361/97194fd8-3242-f95c-a04b-c32d55810e3e.png)

## STEP3：HTMLの作成

さて、HTMLを作成していきます。
まずは、Vue.jsを使って、APIで取得した情報をtextDataという変数に登録します。

```javascript:index.html(下部のjs部分)
    new Vue({
        el: '#app',
        data(){
            return {
                apikey: 'APIキー',
                url: 'microCMSのURL',
                textData: [],
            }
        },
        created () {
            this.setWorkData()
              axios.get(this.url+'エンドポイント名', {
                headers: { 'X-MICROCMS-API-KEY': this.apikey },
              })
              .then(
                  response =>{
                  this.textData =  response.data.contents
              })
              .catch(error => console.log(error))
        },
        methods: {
        ...
        }
    ...
    })
```
そして、HTML上で変数の中身を展開していきます。

```HTML:index.html
    <li v-for="data in textData">
        <div class="text" v-html="data.newsDetail">
        </div>
    </li>
```

これでお知らせ枠が完成して、microCMSの内容が表示されます。

# 懸念点について

## 重くならない？
microCMS上で記事を非公開にすることが出来るので、表示したいお知らせだけに絞って公開する想定でしたら、そこまで通信に負荷がかからなそうです。

それでも気になるようでしたら上限を設定することも可能なので、気になる人は調べてみてください。

## APIキーが公開されるので、セキュリティ的に心配
確かに心配ですよね...
しかし、microCMSはコンテンツの入稿(PUT)や編集(PATCH)、削除(DELETE)の権限を外すことが出来るので、
閲覧のみ(GET)の設定することで、セキュリティ的に突かれる心配はないかと思います。
![スクリーンショット 2022-10-07 17.35.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225361/147e6a4e-8320-8817-43a9-5d2221ca550c.png)

なお、Wordpressも`/wp-json/`でAPIが表示可能なので、投稿して表示させる目的のみでしたら、そこまでリスクはないかと思います。

それでも、どうしても気になるという方は、
Javascriptでapiキーを隠す方法を載せている人もいるので、ご参考ください。
https://zenn.dev/lesserpanda/articles/2baa2f6eed690b

他に方法を調べてみましたが、これといったやり方が見つかりませんでした。

## 下層ページを作りたい！という追加要望が出てきたら?
Vue.jsではルーター使って実現する方法があり、CDNもあるそうです。
一方、CDNでどこまで使えるかは、もう少し調査が必要になるかと思います。
https://v3.router.vuejs.org/ja/guide/essentials/dynamic-matching.html

なので、もし今の段階で要望されたら、
- 基本的にはモーダルで代用
- 下層ページだけどURLが統一された、もしくはGETを使って表示させるような、擬似下層的な感じになる
のではと思います。