占いサービスを支える基盤「Fensi」

平山大暉氏(以下、平山):「CAMがGatsbyで新規サービスを爆速で開発できるワケ」というタイトルで話します。よろしくお願いします。

自己紹介から始めます。2019年新卒の平山大暉です。趣味ですが、最近は外に出ることがなくなってしまったので、掃除にはまっています。特にお風呂場とか洗面台とか、水回りの掃除に最近はまっています。

三好良弥氏(以下、三好):2020年新卒の株式会社CAMの三好といいます。入社してからはずっと占いサービスにかかわっています。最近はシーシャという、いわゆる水タバコにはまっています。おすすめのフレーバーはレモングラスなので、ぜひみなさんレモングラスを試してみてください。

それでは、始めます。

まず簡単に株式会社CAMの紹介をします。CAMでは、有名な占い師が監修しているインターネット占いや、みなさんもご存じのアイドルやアーティストのファンビジネスを中心としたWebサービスを主軸に、toC向けにさまざまなコンテンツを展開しています。

その中でも私たちは、占いサービスに最新技術を注いでいます。本日は占いサービスの「marouge」を中心としたサービスと、その基盤となっている「Fensi」について詳しく説明します。

さっそくですが、この2つのシステムがどのようにかかわり、どのように爆速でWebサービスが作られているかを説明します。

簡単に説明すると、3つの要素でサービスが作られています。まず、データを入稿するためのHeadlessCMSがあります。次に、HeadlessCMSで入力されたデータをもとに、サービスごとの機能にデザインをつけてページを作成するStaticSiteGeneratorがあります。最後に、それを表示させるための各サイトが存在しています。

具体的にそれぞれの段階で何をやっているか説明します。はじめにHeadlessCMSです。CAMでは自作のHeadlessCMSを用いています。これを社内では「Fensi Platform」と呼んでいます。

HeadlessCMSの大まかな機能は、基本的にWordPressと同様と考えてもらってかまいません。管理画面から、テキストや画像・動画などのコンテンツを入力できます。

これはコンテンツとしてブログを投稿する例ですが、上から、コラムの見出し画像、タイトル、本文を入力するようなかたちとなっています。

また、コンテンツの投稿だけではなく、各ページに表示する情報を定義できます。これはとあるページの定義の例ですが、このページでは、ヘッダー、レイアウトでラップされているプロフィール、テキスト、最後にフッターの順番で表示させるのを定義しています。ちなみにこの「TextOne」は先ほどのブログと同様なものを表しています。

このようにページを構成する定義は、HeadlessCMSからWebページ向けのHTMLで提供するのではなく、JSONフォーマットで提供しています。スライドの右側のようにJSONのかたちで取得できて、各コンポーネントの名前やそれに紐づいている子要素など、ページを構成する情報だけです。

各々のサービスで好きなように見た目を変えられる、マルチプラットフォームで提供が可能になるという理由で、JSONのみの提供を行っています。

ちなみにWebページで表示するイメージは、右のような構成のページの作成を想定した定義となっています。

HeadlessCMSから提供されたページ構成情報をもとに、StaticSiteGeneratorで機能や見た目を作成していきます。CAMではStaticSiteGeneratorとしてGatsbyを使用しています。

ページ作成にはReactベースの「Gatsby」を活用

知っている人もいるかと思いますが、簡単にGatsbyについて説明します。

Gatsbyとは、Reactベースで作成されているオープンソースのフレームワークです。StaticSiteGeneratorという側面を持ち合わせています。また、ビルド時にMarkdownやCSVなどをデータソースとして入れられて、GraphQLを使ってそれらのデータを取得できます。

さらに、Gatsby ThemeやPluginという、世の中の人が作ったテンプレートや共通機能をもとに、開発できます。このような特徴があるGatsbyを使用して、CAMではページを生成しています。

Gatsbyを使用したページ生成の流れを説明します。

まず、GraphQLを使用してページを構成する情報を取得します。次にGatsbyの機能である「Theme」と「Plugin」の2つを使って、サイトに共通の機能を埋め込んでいきます。最後にGatsbyの機能「シャドーイング」を用いて、サイトに合った見た目に更新していきます。

1つずつ詳細を説明します。はじめにGraphQLについてです。

先ほど話したFensi Platformで定義した「ページがどのような構成をしているか」というJSONをもとに、Gatsbyのビルド時にそのJSONをデータソースとして渡すことで、GraphQLでデータを取得できるようになります。

このGraphQLで取得したデータをもとにページの骨組みだけを作成していきます。骨組みだけを作成するので、この段階ではまだ機能や見た目はついていません。

次にGatsby ThemeとPluginです。先ほどGraphQLだけを取得して骨組みだけを作ったのですが、この部分に機能をつけていきます。

ThemeとPluginについて、一番有名なThemeである「gatsby-theme-blog」というパッケージを利用したサンプルをもとに、Themeとはどのようなものか説明します。

これは「gatsby-theme-blog」をインストールして立ち上げたときのページです。左側がアクセスした際に最初に表示される投稿一覧のページで、右側が投稿の詳細ページで、ブログに必要な機能がこの段階でできあがっていることがわかります。

CAMでも同じように、よく使う共通の機能をThemeやPluginとして作成して、社内に提供をしています。

Themeを使用するだけで見た目以外の部分ができあがる

ちょっと小さいんですが、これが実際にCAMで作成しているThemeの一部です。

共通する部分のThemeを必要に応じて作成して、テンプレートを積み上げて作成しています。一度Themeを作成すると、それ以降に同じ機能が存在するので、このThemeを使用するだけでその機能ができあがります。

先ほどHeadlessCMSでページ構成を定義した例で言うと、スライドのように対応したThemeが存在しています。このThemeを先ほどの骨組みに組み合わせることで、HeadlessCMSを使用してページの構成情報を定義するだけで機能が完成して、見た目以外の部分ができあがります。これがCAMが爆速で新規サービスを開発できる理由の1つ目です。

シャドーイング機能でさらに開発工数を圧縮

平山:発表者が変わって平山です。最後にシャドーイングについて説明します。

まずシャドーイングについて説明します。シャドーイングとは、Gatsbyが提供している機能の1つです。Gatsby Themeの動作はそのままに、src配下に用意しているディレクトリーを使用者側から上書きして使用できる技術です。

例えば「gatsby-theme-blog」というThemeを使用していて、使い手側はブログの機能はそのままで、見た目だけを少し変えたいとします。このとき使い手側がsrc配下の同じパスに見た目を変えたコンポーネントを配置すると、「gatsby-theme-blog」の対象のコンポーネントが使い手側のものになって、ブログ機能が提供されます。

実際の画面を見ると、シャドーイングしたコンポーネントの部分だけが上書きされていて、ほかの動作はそのままであることがわかります。左側が「gatsby-theme-blog」をそのままインストールして使ったときに出てくる画面ですが、右側がヘッダーの部分だけシャドーイングして……「Hello muddy-web!!」って書いたんですけど、ちょっと赤くて見づらいですかね(笑)。これが置き換わっているのがわかると思います。これがシャドーイングです。

ここで、はじめに説明した図に戻って、実際にシャドーイングしている箇所を確認します。

この部分を私たちは「ジェネレータ」という単位で開発しています。ジェネレータで見た目だけを開発できるので、サービスが立ち上がるたびにジェネレータを作成するだけで開発が完了します。フロントは見た目の部分に集中できて、爆速開発できます。

(次回へつづく)