お久しぶりです。長らくのあいだブログをサボっていた大野です。最近は入社して一年の小林にほぼ全てのバックエンドの開発をぶん投げてフロントエンドばっかりやってます。SMACSS + BEM で作るスタイルシートは素敵ですよ。
当サイトのニュースでもお知らせさせていただきましたが、この度、弊社のオウンドメディアとして Drupal Dawn と称した、Drupal で作られた日本語のサイトを集めたサイトをオープンしました。そのサイトの裏側をブログにしてみたいと思います。
https://drupaldawn.jp/
Drupal 8 がリリースされてからよく耳するようになった「デカップルド」とか「ヘッドレスCMS」。最初聞いた時は「何じゃそりゃ」でしたが、調べてみると Drupal からフロントエンドの部分(テーマ)を外し、API のみを提供して、フロントエンド部分を別のアーキテクチャを使って作る仕組みのことだそうで。さくらのナレッジにジェネロテクノロジーの東さんが投稿されている記事がとても参考になります。
海外の Drupal 記事を見ても皆さん、Decoupled とか Headless CMS って連呼しているので、今回の Drupal のまとめサイトは技術磨くには良い題材だし、流行ってるし、とりあえずやってみるかの適当な精神で Drupal をヘッドレスにして構築してみました。
フロントエンドは最近トレンドのVue.jsを採用しましたが、Drupal を API サーバー化してシングルページアプリケーション(通称: SPA)を作るのはスタジオ・ウミとして初めての取り組みで、一長一短があって、苦労する場面があったのでここに書き留めておきたいと思います。
SPA は画面遷移が無茶苦茶早い。とにかく早い。
シングルページアプリケーションはページの画面遷移が本当に早いです。ページ遷移すると URL は変化しますが HTML 5 の Hisotory API を使っているだけですので、画面の再読込が行われないため一瞬で切り替わります。裏で Drupal で作った API を叩いてテキストを取得してるだけなので当たり前ですが、体感速度としては普通のウェブページとは比べ物になりません。これから書くダメ出しを覆すくらいの効能かなと個人的には思います。
ユーザーからの情報の受け取りが面倒
Drupal の RESTful Web Services モジュールでは、もちろん CRUD (Create, Read, Update, Delete) の処理に対応しています。今回はサイトの登録とお問い合わせフォームを実装しましたが、ユーザーから送信された情報を REST API を通じて Drupal 上に登録するところまではいいのですが、その後に管理者(私達)に内容を通知するのが面倒でした。
普段の Drupal サイトだったら Webform や Contact モジュールを入れて設定するだけのところが、そうはいきません。ノードが登録された時に何らかの方法で通知する処理が必要で、Rules モジュールがα版じゃなくもっと安定していたら良かったのですが、この部分は完全にスクラッチ開発になってしまいました。
SEO に弱い
基本的に SPA のサイトはコンテンツが空の状態に、Java Script (Vue.js) が HTML をレンダリングしてくれるのですが、下手な検索エンジンのクローラーでは JS を実行させることができず、中身が空のサイトとして判断されてしまうことがあります。Google のクローラーは JS でページを描画した後のコンテンツを評価してくれるとのことですが、このサイトがちゃんとインデックスされるか、まだ試せてないので心配です(笑)
ちなみに Vue.js 2.x からは、予め Node.js で HTML を生成するサーバーサイドレンダリングに対応していますが、設定も面倒でインフラ側も対応しなきゃいけないので、これも普通の Drupal サイトを作るのに比べると面倒と感じる部分の一つです。
画像のパスにドメインが付かない問題
Drupal 8 では標準で REST 対応を謳っているのに、なぜか Views で出力する時に画像の URL がドメイン付きのフル URL で出力することができません。/sites/default/files/image.jpg
の様な形で出力されます。フロントエンドとバックエンドでドメインが異なるサイトの場合、データを受け取るフロントエンド側はドメインが付いている http://api.example.com/sites/default/files/image.jpg
みたいな URL じゃないと困るんです。
この問題については Image URL Formatter モジュールを入れることで無事解決しましたが、これは是非コアにも取り込んで欲しい機能の一つです。
スクリーンショットは Google Chrome のヘッドレスモードで自動化
何百もあるサイトのスクリーンショットを手動で撮るなんて事は絶対にしたくなかったので、自動化が最重要と考え、最初に Phantom.js の利用を検討しましたが、試してみると CSS の flex: box
に対応しておらず、最新の CSS を使ったウェブサイトは軒並み崩れてしまって、使い物になりませんでした。
そんな最中、丁度よく Google Chrome にヘッドレスモードが搭載されることを知りました。ここで言うヘッドレスはヘッドレスCMSとはまた違うもので、Google Chrome から GUI を排除して、コンソール上でブラウザを操作することができるものです。試しに使ってみたところ、普段使っている Chrome のレンダリングエンジンがそのまま使われるので、崩れるはずもなく、かなり良い感じにスクリーンショットを自動化して取得できるようになりました。(それでも課題のあるサイトもいくつかありましたが)
当サイトでは、Drupal の cron 実行時にバックエンドで動いているヘッドレス Chrome と 連携してサイトのスクリーンショットを撮影しています。
HTTP アクセス制御 CORS の問題
フロントエンドとバックエンドでドメインをまたぐ場合、HTTP アクセス制御 CORS の問題にぶち当たります。Drupal 8 からは標準で Access-Control-Allow-Origin
の HTTP ヘッダーが付与されるようになって、簡単に言うと違うドメインのサイトからはJSでアクセスすることができません。これは sites/default/services.yml
を有効にして cors.config
の allowedOrigins
に許可するドメインを設定することで回避することができます。
余談ですが、allowedOrigins
の設定値は配列になっているので、複数のドメインが設定できるのかと思いきや、そうでもなく、最後に設定されたドメインしか有効にならないようで無駄にハマりました。Access-Control-Allow-Origin
は仕様上、一つのドメインしか設定できないのでそうなっているんだと推測しますが、「配列にセットしてあるドメインからのアクセスであれば、よしなに変えてくれたら良いのに」とか思ったりもしましたが、きっと何か問題があるのでしょう。(動的に変えたい場合はウェブサーバー側で対応することが多いみたいです)
標準のシリアライザの使い勝手があんまり良くない
今回作ったサイトではウェブサイトデータを登録するためのコンテンツタイプがあり、それには色などを分類するためのタクソノミーのフィールドがあります。Views の REST Export で Format を Serializer にすれば、ターム名称とかも上手く入った良い感じの JSON が出てくるもんだと、そんなふうに考えていた時期が私にもありました。
試しに設定して出てきた JSON データは次のようなものでした。
"field_site_colors": [
{
"target_id": 1,
"target_type": "taxonomy_term",
"target_uuid": "8b28283b-3d2f-47c5-a805-000000000000",
"url": "\/taxonomy\/term\/1"
}
],
えっ、ターム名称は?。ターム名称はどこさ!こちとらフロントエンドで表示したいのは uuid とかエンティティタイプじゃなくて、ターム名称!
…設定でどうにかなるんだろ、と思ってましたがどうにもならず。結局のところスクラッチ開発で専用のシリアライザを実装してしまい、Drupal を使ってるのにあんまりエコな感じにすることができませんでした。もし、良いやり方をご存知のかたはこっそり教えて欲しいです。
まとめ
現段階では Drupal 単体で REST API をコードを書かずに実装するのは、まだ厳しいかなと言う印象です。今後のバージョンアップによるアップグレードを期待します。
現在、全部で400件弱のサイトを登録していますが、まだデータはあるけど未登録のサイトが500件以上あります。スクリーンショットは先述の通り自動化して撮影していますが、人の目で見てデータ入力してるところもあるので、スローペースですがこれからもっと充実させていくつもりです。
データを集めてみて、意外にも誰もが知るサイトにこんなに使われているんだなと驚きました。有名企業のサイトは外資系が多いのは仕方ないですが、国内の大手企業の採用がもっと増えていくと良いですね。最近は Drupal を扱われる制作会社さんも増えてきた気がしますし、Drupal の流れは着実に来ていると感じる次第です。
もしまだ掲載されていない Drupal サイトをご存知でしたら、是非サイトの登録ページからお知らせください。また、制作会社の方は、Drupal を知らないお客さんに「Drupal はこんな色々なサイトでも使われている!」と説得するための材料の一つとしてお使いいただければと思います。
募集しています
スタジオ・ウミは「Drupal」に特化したサービスを提供する Drupal のエキスパートチーム。
フルリモート&フレックス制だから、働く場所を選ばず時間の使い方も自由です。
そんなワークライフバランスの整った環境で、当ブログに書かれているような
様々な技術を共に学びながら、Drupalサイト開発に携わってみたい方を募集しています。
まずはお話だけでも大歓迎!ぜひお気軽にご連絡ください。