次世代Headless CMS「contentful」事始め

この記事は [ハンズラボ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/handslab) 2日目の記事です。


ハンズラボのアドベントカレンダーがみるみる埋まっていくのを見て、一人ニヤニヤしていた@daikiojmです。
7月にハンズラボに入社して以来、Angluarでフロントエンド開発をしています。
今回は、個人的に気になっていた、[contentful](https://www.contentful.com/)の概要と、ハンズオンの手順をまとめてみます。

# 概要

contentfulはAPIファーストなCMSで、ドイツのスタートアップによって開発されており、WordPressやDrupalなどの従来のCMSとは異なり、ディスクトップやモバイルだけでなく、デジタルサイネージや、スマートウォッチなどのプラットフォームへのコンテンツ配信が可能なAPIが用意されていることが特徴です。

WordPressなどと同様に、記事(コンテンツ)の投稿、管理画面のUIは用意されていますが、ユーザーが記事(コンテンツ)を閲覧するUIは用意されておらず、開発者はREST API経由で記事(コンテンツ)を取得し、アプリケーションやデバイスのUIに反映させます。

2017年12月現在、日本語で使い方を紹介した記事などはあまりなく、[2017年のフロントエンドエンジニアならこの程度は知ってて当然だよな？](https://qiita.com/rana_kualu/items/cad8dbbe5f5a1f1b3ba1)というQiitaの記事で存在を知りました。
インターフェースがREST APIに統一されているという点で、SPAとの相性もいいのではないかというのが、気になっていた理由の一つでもあります。

# ハンズオン

公式ドキュメントのチュートリアル「[Get started with Contentful](https://www.contentful.com/developers/docs/tutorials/general/get-started/)」を進めてみたいと思います。
この手順を進めると、アカウントの作成からNuxt.jsを使ったブログサンプルの構築が行なえます。
前提としてnpmまたは、yarnが使える環境である必要があります。

## CLIツールのインストール

次のコマンドで、[CLIツール](https://www.npmjs.com/package/contentful-cli)をインストールします。

```bash
$ npm install -g contentful-cli
```

or

```bash
$ yarn global add contentful-cli
```

インストールが完了すると`contentful`コマンドが使えるようになっているので、
次のコマンドを実行します。

```bash
$ contentful guide
```

次のように質問されるので、`Yes`と答えます。

```bash
? Open a browse window now? Yes
```

## アカウント作成とログイン

前記コマンドを実行すると、ブラウザが立ち上がり次のような画面が表示されるので、いずれかの方法でアカウントを作成します。今回は、Googleアカウントでログインしました。

![スクリーンショット 2017-11-26 22.41.11.png](https://qiita-image-store.s3.amazonaws.com/0/79414/b072cd64-b84b-ea54-6414-92db81891da4.png)

次の画面では、名前、メールアドレスの確認と所属組織を入力して、「Sign Up」をクリックします。

`Authorize Contentful CLI to use your account?`と聞かれるので、「Authorize」をクリック。

  ![スクリーンショット 2017-11-26 22.43.27.png](https://qiita-image-store.s3.amazonaws.com/0/79414/928926d4-71e3-7601-4a1e-a5bae3f56850.png)

画面に表示されるaccess tokenをコピーします。 

CLIに戻り、コピーしたtokenを貼り付けます。

<img width="1242" alt="cliにトークン.png" src="https://qiita-image-store.s3.amazonaws.com/0/79414/4cd4e8c4-89fd-35d0-db12-95f893569a6b.png">

## スペースの作成

コンテンツを管理する単位はspace(スペース)となっているようです。
ここでは、CLIからスペースの作成を行います。


認証に成功すると、次の手順に進み、下のような質問をされるので、任意のスペース名を入力した後に、`Yes`を選択します。
ここでは、hands-onとしました。

```bash
? Wich name for the Space would you prefer? hands-on
? Create your new Space now? Yes
```

ウィザードに沿って進めているので、自動で作成されるようですが、手動で作成する際は次のコマンドを実行することでスペースの作成ができます。

```bash
$ contentful space create --name hands-on.
```

次のような結果が表示されればOKです。

```bash
✨  Successfully created space hands-on (6x2w5ho8o027)
```

## コンテンツモデルの作成

ここでは、投稿の雛形を作成します。
テンプレートを使って、ウィザード通りに進めてみます。

次のように聞かれるので、`Yes`を選択します。

```bash
? Populate the Content model to your Space now? Yes
```

次のコマンドが実行されて、静的ページとブログ記事ページの雛形が作成されます。

```bash
$ contentful space seed --template blog --space-id 6x2w5ho8o027.
```

完了すると、次のような結果が表示されます。

```bash
...
┌──────────────────────────────────────┐
│ The following entities were imported │
├───────────────────────────┬──────────┤
│ Content Types             │ 2        │
├───────────────────────────┼──────────┤
│ Editor Interfaces         │ 2        │
├───────────────────────────┼──────────┤
│ Entries                   │ 4        │
├───────────────────────────┼──────────┤
│ Assets                    │ 4        │
├───────────────────────────┼──────────┤
│ Locales                   │ 1        │
├───────────────────────────┼──────────┤
│ Webhooks                  │ 0        │
├───────────────────────────┼──────────┤
│ Roles                     │ 7        │
└───────────────────────────┴──────────┘
info import The import took a few seconds (31s)

✨  The Content model was applied to your hands-on (6x2w5ho8o027) Space.
```

## サンプルアプリの起動

ここでは、[blog-in-5-minutes](https://github.com/contentful/blog-in-5-minutes)というNuxt.js(Vue)で作られたブログサンプルをローカル環境に立ち上げます。

次のように、カレントディレクトリにサンプルアプリを置いていいかを聞かれるので、`Yes`とするか任意のディレクトリを選択します。

```bash
? Is the path above okay? Yes
```

リポジトリのクローンとパッケージのインストールが終わると、次のように聞かれるので、`Y`を選択して開発サーバーを立ち上げます。

```bash
? Run Custom app locally in development mode now? Yes
```

ブラウザから、`http://localhost:3000`にアクセスすると、ブログが表示されます。

## 記事追加

次に、Webの管理画面上から記事を追加して開発サーバーのブログアプリに反映される化を確認してます。

まずは、以下から先ほど作成したアカウントor連携アカウントで管理画面にログイン
https://app.contentful.com

画面左側のメニューから、先ほど作成したスペースを選択した後、「Add entry」のボタンから「Blog Post」をクリックします。

![スクリーンショット_2017-11-27_0_41_53.png](https://qiita-image-store.s3.amazonaws.com/0/79414/16eb726c-cddc-5f07-ab5c-51c02b374f45.png)

タイトル、body、tagなどの必須項目と、アイキャッチ画像をアップロードし、「Publicsh」ボタンをクリックします。

![スクリーンショット_2017-11-26_23_10_24.png](https://qiita-image-store.s3.amazonaws.com/0/79414/84540408-738c-94ef-edc4-6fe74ad4db31.png)


## 確認

ブラウザで開いている `http://localhost:3000/blog`にアクセスすると、管理画面から追加したブログポストが追加されているのが確認できるかと思います。


![スクリーンショット_2017-11-26_23_13_48.png](https://qiita-image-store.s3.amazonaws.com/0/79414/359c1188-d998-232e-26ef-bee1957979ec.png)


# 機能

ハンズオンでは、管理画面からの記事投稿、REST APIでの取得を紹介しましたが、
その他にも次のような機能が用意されているようです。

* スケジュール投稿
* 新規投稿時のWebhook(からのPush通知など)
* ユーザーごとの権限設定
* 記事の検索

※一部抜粋


# 終わりに

APIファーストをうたっているだけあって、公式のSDKなどがかなり充実している印象です。
既にWordPressなどのCMSを使っている場合の置き換えに関しては、よくわかりませんが... 「WordPressなどの経験は無いけど、ReactやAngularでフロントは書ける!」という場合には、選択肢としてありじゃないかとお思います。
contentfulの他にも同様のコンセプトのCMSで、[Cosmic JS](https://cosmicjs.com/)や[prismic.io](https://prismic.io/)というサービスもあるようです。

[ハンズラボ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/handslab) 3日目の明日は、こちらも2回目の@watarukuraさんです✨


# 参考

[Headless CMS -Qiita](https://qiita.com/reflet/items/55665a79940a96252c68)
[ベルリンの「Contentful」が1300万ドルを調達、最先端のプラットフォーム向けCMSの拡大目指す -THE BRIDGE](http://thebridge.jp/2016/06/berlins-contentful-raises-13-million-to-grow-its-api-driven-content-management-system-in-the-u-s)
[How to build a React Redux application with API-first CMS Contentful -Medium](https://medium.com/geogo-in/how-to-build-a-react-redux-application-with-api-first-cms-contentful-84efdd7ee654)