CARTA HOLDINGSで働くエンジニアたちにCTOが「最近何やってるの?」をざっくばらんに聞いていくシリーズです。今回はCARTA HOLDINGS CTOのすずけんが、事業子会社のひとつであり「神ゲー攻略」などのメディアを運営するLighthouse StudioでCTOを務める海老原さんに話を聞きました。
インタビュアー:鈴木健太 Twitter ID @suzu_v(写真右)
株式会社CARTA HOLDINGS 執行役員CTO / 株式会社fluct取締役CTO。社内では「すずけん」と呼ばれる。「みんなのGo言語」「データ分析基盤入門」共著者。ウェブ技術全般に明るい。ポッドキャスト「ajitofm」をやっています。
インタビュイー:海老原昂輔 Twitter ID @co3k(写真左)
株式会社CARTA HOLDINGS / 株式会社Lighthouse Studio取締役CTO。社内では「えびちゃん」と呼ばれる。ウェブ開発を主戦場としつつ、サーバ運用やスマホアプリ開発についても幅広い知識や経験を有し、ウェブセキュリティが得意技。Lighthouse Studioは国内最大クラスのゲーム攻略サイト「神ゲー攻略」を運営しています。
Lighthouse Studioの近況
鈴木健太(以下、すずけん):今回はLighthouseの近況というか、2022年になっての内部環境・外部環境みたいな状況や、えびちゃんから見てどんなチャレンジがありそうかなど、ざっくばらんに聞きたいなと思っています。
海老原昂輔 (以下、海老原):まあ......いろいろありましたね(笑) 内部環境・外部環境ともに本当にいろいろ起こっている状況です。『Engineers in VOYAGE』で話したとき、「そーだいなる VOYAGE GROUP の裏側」イベントで話したとき、SSRにリプレイスしたというブログ記事を書いたとき、それぞれの時期と比べて、実は外部環境は変化していて。
すずけん:うんうん。
海老原:一応、我々(神ゲー攻略)が業界3位にいるという認識は変わっていません。(『Engineers in VOYAGE』発刊)当時は業界トップの背中にかなり迫ってきており「いよいよ追い抜くぞ」というムードだったんですけど、最近は競合サービスの勢いが増してきており、せっかく追いついたと思った背中が遠ざかってしまった。その一因となったのが、昨年(2021年)の夏〜秋頃にあったGoogleのコアアルゴリズムアップデートです。このコアアルゴリズムアップデートで、E-A-Tと呼ばれる基準を満たしているかどうかがより重視されるようになったなどの変化があり、結果として競合サービスよりも神ゲー攻略が相対的に低く評価されるようになってしまった。これは大きな痛手です。そういったわけで、現在てんやわんやになりながら要因を分析して対策を打とうとしているところです。
すずけん:Googleが掲げている、その、E-A-Tというのはどういう基準なんでしょうか?
海老原:これは「Expertise(専門性)」「Authoritativeness(権威性)」「Trustworthiness(信頼性)」の略語で、一言で言うと、コンテンツ自体の内容だけでなく、「このコンテンツの作成者が、妥当なコンテンツを生み出す蓋然性」について見られるようになったということだと捉えています。
すずけん:つまり、競合サービスでは、コンテンツ自体の内容に直接的に関わる以外の施策まで含めてしっかりやっていたということでしょうか?
海老原:そういうことだと捉えています。我々(神ゲー攻略)は愚直に、いい記事をたくさん出そうという部分にフォーカスして頑張っていて、直接コンテンツ自体の内容に関わらない施策は二の次というか、重視していなかったというのが正直なところなんですよね。この点において競合サービスとの差分が明確にあった。そして我々にとっては不幸なことに、この差分が(コアアルゴリズムのアップデートで)Google検索上、かなり重視されるようになってきてしまったのです。
すずけん:なるほど。Googleのコアアルゴリズムのアップデートで神ゲー攻略の順位が厳しくなってきたとは聞いていたのですが、内部的にどういう意味合いだったんだろうというのが、いまの話を聞いてわかりました。
海老原:3位というのは変わらないんですが、以前とはうってかわってかなり危機感を持っている状況ですね。
組織の変化と向き合う
海老原:そして内部環境的なところでは、まず人が増えました。これ自体はグッドニュースですが、(これまでLighthouse Studioで一緒にやってきたエンジニアの)「のざ」とか「にっしー」の場合は、僕と距離がずっと近く、べったりくっついてやっていたので、本当に以心伝心というか、「『いい感じ』にやっておいて」みたいな割と雑なコミュニケーションでもでも「いい感じ」になっていた。ただ、これは全然再現性がないんですよね。それなりに時間をかけて一緒に問題に取り組んでいくなかで偶発的に育まれた関係性だった。いざ人が増えてくると、そういう(関係性でカバーしていた)部分でのズレというか「そこまではやりすぎなんじゃない?」とか「それは事業的にうれしくないんじゃない?」みたいなギャップが、ちょこちょこ出てくる。細かい部分の、文化的な、言語化しにくい部分での意思疎通がちょっと弱くなってきたなと感じます。
すずけん:にっしーって何年目でしたっけ?丸4年?一緒にやって1000日くらいか。のざ、にっしー、えびちゃんでいうと、もう文化が共有されていて、暗黙的な了解がお互いにありますよね。一緒に作ってきたし、レビューも濃くやってきたし、考え方がすごく伝わっている。
海老原:しかもプロダクトのわりと初期の、何も整っていないころから見ているのもあるし。出来上がってからジョインした人と、出来上がる過程で接してきた人とは、その見え方が違うのは当然で。そのあたりの言語化できていないところをうまく伝えて、認識のギャップを埋めるところが全然できていない。人が増えていくなかで、同じように全部まるっと「オーナーシップを持ってやってくださいね」って雑に仕事を振ってどうにかなるわけじゃないんだなというのがわかってきた。いずれ起きるんだろうなとは思っていたけれど、これくらいの人数規模でも起きるんだというのは僕のなかでは想定外でした。
すずけん:なるほど。10-15人では起きるかもしれないが、6人でも起きるのかー、ということですね。
海老原:はい。個々のタスクレベルではめちゃくちゃズレがあるというわけではないんだけれども、だんだんこう、ちょっとずつちょっとずつ......。大きなタスクがあって、一連の細かいタスクのなかでちょっとずつズレていって、結果として「あれ?これひょっとして大きなズレだったかもしれない」って気づく、みたいな。
すずけん:今日、えびちゃんと話すにあたって、ひさしぶりに『Engineers in VOYAGE』を読み直してきたんですよ。のざ が「投資しすぎない」とか「小さく始める」みたいなことはLighthouse入って学びました、って話をしていて。えびちゃんの考えは、旧VOYAGE GROUPのみんなの共通認識だし、文化として持っていたなと思っていて。これをあとから入ってきた人にどう継続して伝えていくかっていうのはまさに、CARTA HOLDINGSとしても直面している課題かなと。
海老原:そうですね、のざ とか にっしー の場合は僕が直接見ていたので、言語化しにくい精神性の部分って伝えられたんです。僕としては正直伝えたつもりはないんですが(笑)、結果としては伝わっていた。しかし最近は、僕自身が新規メディアなど(他の開発メンバーとは離れて)いろいろやるようになってきて、のざ や にっしー に神ゲー攻略のほうを任せてしまっています。もちろん、のざ や にっしー は、そういう精神性の部分はわかってくれています。ところが、僕が伝えていたのって、あらためて考えてみると、これまでの自分のエンジニア人生で試行錯誤してきて、アンチパターンとかもたくさんやってきたなかで、血となり肉となっていた部分だったんですよね。それを伝えてはきた。だけど、のざ や にっしー は、アンチパターンに直接触れているわけではなくて、僕から聞かされて「教訓」として受け取っている。結果としてリアリティが損なわれてしまうので、うまく「伝道」していけているのか?うまく「浸透」してているのか?という点で懸念があります。いまのところ人数は増えたんですが、スケールのさせ方としては不完全。そこをどうしていくかは悩んでいるところですね。
すずけん:なるほどね〜。これはめちゃめちゃ課題ですね。僕たち、「失敗しよう」とは言うけどね……僕もえびちゃんも、僕らがやらかしてることって実は結構あるはずで。’養殖モノ’ の失敗ではないというか、やったうえで言葉にしているから当然説得力があると思うんですよね。そうじゃなくて伝え聞いたアンチパターンとして「ボブおじさんから聞いたんです」と伝えるのって(伝えられる側の)本人たちからすると難しいですよね。
海老原:僕らはエンジニアなので、何かよくないことがありそうだったら仕組みで解決しようとするじゃないですか。再現性をもった解決方法、根本から解決するというアプローチをするので、どんどん失敗しにくくなる。いいことではあるんだけれども、それをやってしまうと、失敗しないで済んでいる環境が当たり前の人にとっては「なんでこういうセーフティネットが張り巡らされているんだろう」って疑問に思うことになる。いや、人によっては疑問にすら思わないかもしれない。「なんのためにあるかわからない」。恩恵に与っているとどうしてもそうなってしまう。
すずけん:fluct(CARTA HOLDINGSの事業子会社のひとつ)でもCI/CDを2013-2015年くらいに一気に整備したんです。結果的にデプロイとかリリースがすごく楽になって、それまで謎のMakefileとかたくさん動いてて(笑)、だけどそのあたりが整っていった結果、あとから入ってきた人たちってそれが普通なので、CircleCIからリリースすればそりゃあリリースできますよね、みたいな。結果失敗はたくさんしているはずなんだけど、なんでそれがあるのかっていう必然性は実は知らない。リリースが遅いと何が問題なのかは肌感がない。
海老原:かといって、意図的に事業上インパクトのある失敗はさせられないですしね。
すずけん:細かく失敗させたいっていう気持ちもあるけど、そのインパクトのない失敗って本人たちにもインパクトがないので......。いい仕組みを作った結果、失敗ができなくなるジレンマみたいな。精神性の再現性の話ですよね。
海老原:僕はいま新規メディア周りをやっていますが、どうしてもプレイヤーとして活動しているとそこまで手が回らないという問題があります。いま決断を迫られていて。これまでプレイヤーとしてやるってことにめちゃくちゃこだわっていたんですよね。現場感のない人にマネジメントされたくないでしょって僕は思ってて。outdated な技術を押し付けたりとかは嫌だったので「現役のエンジニアとしてやっていくなかでマネジメントもするよ」みたいな感じだった。でも僕もちょっと大人になったので(笑)、自分の使える時間にも限りがあるのもわかってきた。現役の一線級のプレイヤーとしてもやりつつ、そういう精神性であるとか、見過ごされがちな細かい部分まで目を向けてメンバーをマネジメントするということの両立ができないというフラストレーションを、この1年ずーっと感じてきた。
すずけん:なるほどねーーー。そうだよなあ。時間が2倍あればね・・ないですからね(笑)
海老原:はい、僕がふたり欲しいっていう話ですね(笑)
すずけん:Zucks(CARTA HOLDINGSの事業子会社のひとつ)の河村さん(Zucks CTO)も同じ話を結構していましたね。マネジメントタスクとプロダクトを作る両方をガッツリやっているけど、チームを見るのは分けたいなという話はずっと出ていて。結局、今月(2022年2月)から分けるっていう話になりましたよね。やっぱりモノを作っていくときに突っ走っていく、その精神性を100%発揮する仕事と、伝えるっていう仕事、合わせて200%になっちゃうから......。
海老原:そうそう。どこかが疎かになる。
すずけん:わかるなあ。えびちゃん的には、まさに時間をどう使っていくかが課題だし、新しく入ってきたふたりがもっとそういうものを身につけていくようにするか、それとも自分でコードを書くかっていう天秤をこの半年、1年ずっとやっているんですね。
海老原:目下考えていることとしては、いま作っている新規メディアはローンチしなきゃいけないので、そこはプレイヤーとしてめちゃくちゃ頑張る。リリースまでは漕ぎ着けて、細かい改善とかはやっていく。神ゲー攻略に関しては、のざ、にっしー お任せでいいだろうと。事業責任者の友幸さん(Lighthouse Studio代表取締役)もそこは助けてくれるので。で、プロダクトを見る負担を軽くして、メンバー周りや採用、育成に徐々に注力してバランスをそちらに傾けていこうかなと。いままでは中途半端だったので、しっかりシフトしようとしています。
すずけん:さっき言ってた「現場感ない人にマネジメントされたくない」というのとね(笑)
海老原:そう、そこは矛盾と戦わなきゃいけない。本当にそうですね。
すずけん:僕も1月から(CARTA HOLDINGS CTOになって)、まだすごくふわっとしていますね。いまもfluct CTOでもあるんですが、2022年に入ってこの1ヶ月間くらい、本当に大きなプロダクトマイルストーンのときだけfluctの開発チームのディスカッションに入るものの、日々のイシューとかは全然見えない。そうなったときに、「すずけん、なんか的外れたこと言ってくるな〜」って絶対どこかでなると思っていて。たとえば「いまってNext.jsが一番いいんでしょ」とか、いやいや何言ってんの〜って絶対新卒とかからも言われるので(笑)
海老原:その恐怖心はありますね。ただ、時代遅れな意思決定をしたくないというのは一種のプライドだったんですが、でもひょっとしたら過剰すぎたかも、とも思っています。半年くらいは離れていても大丈夫じゃないか? って自分のなかでは言い聞かせていて。半年くらいは、ちょっとプロダクト開発で忙しくてキャッチアップが遅れるのはあり得る期間だなって思い込もうとしています。
すずけん:わかります、わかります。テーマとして、単位時間での成長、たとえば、自分がプロダクトを作っているなかで技術的に何が成長したか、3ヶ月とか1年、プロダクト作っているときに自分がどんな新しい知識を身につけて、どんな判断力が上がったんだろうっていう尺度の成長と、たとえば、半年くらいマネジメントをしていて、そのあと一気にテクニカルなキャッチアップをしたときと、結果どれくらい何が変わるんだろうなっていうのは、結構思考実験をしたんですよ。CARTA HOLDINGS のCTOになるときにね。プロスポーツ選手とかだと、筋肉が落ちて戻すの大変とかあると思うんですけど、僕らの場合は知識なので、キャッチアップの効率が上がれば一応なんとか1年みたいなスパンで見ると底上げはできるのかなって思ってはいるんですけど。
海老原:我々の場合、ある程度長年やってきたという貯金があるじゃないですか。技術ってゼロスタートで発明されるものって少なくて、だいたい連続的なんですよね。和田さん(@t_wada)がよく「技術の変化は螺旋である」と喩えていらっしゃいますけど、ぐるぐる同じようなところを巡っているので、これまでの貯金分を活かして、キャッチアップがちょっと遅れた最新技術も、ゼロからキャッチアップする人よりはおそらく速いスピードでついていけるはずなんです。そこのアドバンテージをおそらく活かすことができるはず。
すずけん:そうなんですよ。......というのを頭では思っていても、離れるのは怖いんですよね(笑) 僕はいまだに思っていますね、やばいなって。GitHubの草が薄れていく、大きな怖さはすごくありますね。でも本当に新しい概念がバーンて出てくることはなくて、どこかで連続はしているから、あるポイントでちゃんと追っていけばよいのは確かです。いきなり3年後に、リレーショナルデータベースがまったくいらないってことにはならない。
海老原:そういう技術トレンドがくる可能性は全然あるけど、またリレーショナルデータベースに戻ってくる。
すずけん:うんうん。
Lighthouse Studioが持つ、メディアを作る力
海老原:新規メディアとか、そのへんの話もしていきますかね。外部環境に絡むところではあるんですが、ゲーム攻略サイトというものがあとどれくらいの伸び代があるのかというのは、結局ターゲットである「スマホゲーム市場」と「コンシューマーゲーム市場」のふたつを合わせた市場規模が天井なんですよね。更にいまのゲーム攻略サイト市場をみたとき、神ゲー攻略はおかげさまで2.2億PV、競合他社さんとかはざっと倍近くある。ゲーム攻略サイトというものに対してニーズがある人の数というのはそれくらいの規模で頭打ちになっちゃうんですよね。
すずけん:(ゲーム攻略サイト市場全体でいうと)15-20億PVくらい?
海老原:もう少し減ってくるかもしれませんが、それくらいがアッパーでしょうね。これまで神ゲー攻略はトントン拍子で右肩上がりに成長してきたんですが、どこかで限界がきてしまう。長期的に見て同じような成長曲線は描けないだろうなと考えています。我々自身としてターゲットとなる層を広げるっていうのは当然やってはいくんですが、同時に新しい領域も攻めていかないと、会社として同じような成長曲線は描けないと思っています。……という背景があって、新規メディアを始めます!という流れですね。ゲーム攻略サイトにおいて後発でありながら、一気に業界3位まで上り詰めているので、そこでのノウハウや経験を、ほかの事業領域に対して展開していって、同じような成功体験をつくるというのができるのじゃないかなという。
すずけん:これまでに積み上げてきたLighthouseのパワーって、システムもそうだし、ライティングする組織を作るとか、そういうところにあるんですかね。
海老原:ライティング組織を作るっていうのは事業責任者の友幸さんがものすごくきっちりやってくれていたところで、これはめちゃくちゃ力になっていますね。しっかり評価の高い記事を書くっていうことに対しての仕組みづくり、たとえば、「こういう風に書いていきましょう」「こういうモニタリングをしていきましょう」といった方針を決めたりとか、再現性を持って実現していくための組織体制を、しかもスケールする形で作ったり、かつ、成果を出した人に対してしっかりした評価、報酬をもたらすところであるとか。そこに関しては掛け値なしで業界で一番うまくやれる自信がありますね。これは本当に友幸さんがすごいって話なんですけど。
すずけん:ゲーム攻略サイトとしてユーザから見えている部分以外の、ライティングする組織を支える裏側の仕組みとかは『Engineers in VOYAGE』のなかでも触れられていたとおり、注力してやっているところですよね。
海老原:我々のような形態のメディア企業にとって大事なのってコンテンツなので、そのコンテンツを生み出す力をより強化する。ここが一番大事なんだとしっかり自覚してやっていますね。
すずけん:ライティングによってコンテンツを生み出す力、そしてそれを加速させるプロダクトや組織作りといった強みをいまLighthouseは持っているわけですよね。一方、ライティング組織っていまだと、ゲーム向けのライターさんが中心で、仕組みとしても、たとえばガチャシミュレーターみたいなものもゲーム向けに特化したツールであると。こうしたなかで、別の業態だったり、別ジャンルのメディアだったりに対しても、再現性を持ってアプローチできるのか——つまり、ゲーム攻略だけではなく他の領域にいってもいけるなっていう感触を、Lighthouseの経営陣からすると持っているわけですか?
海老原:はい、そうですね。勝負する業界によってアウトプットの出し方とか運用の仕方は変えていくんですけれども、アウトプットを生み出すための仕組みとかノウハウはある程度抽象化された形で、再現性を持って同じような形で取り組めるのではないかと思っていて、いまはそういう形で組織もシステムも作り上げていっていますね。
新規メディアの新たなアーキテクチャ
すずけん:たとえば今回新しく作っている新規メディアでも、ライティングのチームを別途作って、仕組みとしてもCMSというか、コンテンツを書ける仕組み、パブリッシュする仕組みをそれぞれ設計して作っていっているんですか?
海老原:はい。ほとんどできていますね。そのあたりの技術的なところも深ぼっていければと。
すずけん:作るの2周目?3周目かもしれないけど(笑)アーキテクチャとか、問題に対するアプローチとか全体プロット設計って今回どんなしきりで始めていったんですか?
海老原:神ゲー攻略でやったコンセプト自体は基本的には悪くなかったと思っていて、設計するうえでのベースになっています。コンセプトというのは、たとえば、lit-htmlのような軽量な仕組みを使ってSSRを実現したということ。それから、パブリッシュされる記事と内部的に管理する記事でストレージを分けたこと。内部で扱っている記事はMySQLで、そこのMySQLは基本的にはメタ情報含めてフルの情報が入っているんですが、そこから射影関数を通してデータストアに反映していくと。エンドユーザは公開用に射影されたCloud Datastoreのレコードだけを取得しているので、編集上必要な内部情報が露出したりする危険はないし、かつエンドユーザが見るデータ取得操作はシンプルなので、 ‘ちょっぱや’ で取得することができると。
すずけん:なるほど。前もそうでしたけど、読む側はシンプルなマクロで高速に読めばいいと。
海老原:はい、そういうコンセプトは踏襲しています。
すずけん:神ゲーのほうは、2019年に、「ついにRDBMSに記事データが載った」ということでしたよね。初期はMarkdownファイルが生でストレージに置かれていたのが、記事データとしてRDBMSに保存されるようになったという。今回はその(RDBMSに記事データを置くようにした)状態が出発点ということですね。
海老原:はい、そうです。ただ神ゲー攻略の反省点はいくつかあって。まずlit-htmlを使っていることが反省点なんですけど(笑)lit-htmlは目的に対しては最適な手段だったとは思うんですが、あまりにメジャーじゃない。誰も知らない(笑)
すずけん:いまわかったことじゃないですよね(笑)
海老原:まあ難しいところでして、Virtual DOMを避けて、SSRを低コストでできるというところはよかったんですけど、これがlit-htmlじゃなければな、という。ただ、当時としてこの選択肢が最良だったと思っています。
すずけん:じゃあ、「いま」開発中の新規メディアでは、Svelteとかを使っているわけですか?
海老原:鋭いですね。その通りでして、新規メディアではSvelteを選択しています。
あと、 lit-html自体は単機能なものなので、SPAとしての遷移であるとか状態管理であるとか、あとはSSRの機構も含めて、ありとあらゆるものを基本的には自作したんですよね。自作といってもルーティング機構とかはrouter5使っていたりとか、状態管理はRedux使っていたりとか、そういう「いい部品」を組み合わせてはいるんですが。ただ、やっぱりSPAだとユーザクリックのハンドリングみたいなことだとか、ページ遷移であるとか、ブラウザがやっていたことを自分たちで再実装しないといけないところがあるんですね。そのへんをご多分に洩れず自分たちで再実装するハメになったのが、無駄といえば無駄だったと思います。ただ当時はそうするしかなかった(笑)
すずけん:なるほど(笑)ページ遷移でHistory APIを叩いてルート追加して、かつ画面のステートが切り替わって……以降のところは全部自分で作るしかなかったという。
海老原:そうですね。ルーティングライブラリの力は借りているとはいえ、たとえば、「ページ内遷移はどうするか」というのは自分たちで書かなきゃいけなかった。一時的にルーティングライブラリの管理から外して、スクロールをちょっと再現して、とか。
すずけん:スクロールねー、地味に面倒ですよね。
海老原:本当にそうですね。ちょうどいい位置に要素を持ってこなきゃいけないし。ページ内をハッシュパラメータ付きで遷移した場合と、別ページからハッシュパラメータ付きで遷移した場合とでは、動きとかスクロールするべきタイミングが異なったりする。そのへんはブラウザであれば通常の遷移のなかでうまくやってくれたんですけれど、SPAだとそこは自分たちで、ページがレンダリングされたタイミングをイベントとかをうまくlistenして、制御させなきゃいけない。
すずけん:そうですよね。データ読み込まれてページ要素がだいたいできてからスクロールしたいから。そうしないと先にスクロールすると「え、まだないし」みたいな。ブラウザからすると。
海老原:そのへんは伝統的な(SPAでない)アプリケーションであれば、ブラウザがいい感じにしてくれたところを、自分たちでやんなきゃいけない苦しみっていうのは、こういう形態のアプリケーションを作っていると、どうしても出てくること。めちゃくちゃ車輪の再発明をしている感はありました(笑)
すずけん:(笑) SPAってだけでもこれだけいろいろあるうえに、SSRもしているわけですからね。
海老原:はい、そっちはそっちでまた車輪の再発明が発生しています。SPA部分やSSR部分もひっくるめて自作していたのが神ゲー攻略だったんですが、新規メディアでは、まだパブリックベータではあるものの、SvelteKitというものを使おうとしています。これは、ReactでいうところのNext.js、Vue.jsでいうところのNuxt.jsみたいな位置づけのSvelte版フレームワークです。SPAならではのエンジニアリングをしていたところも、SSRの機構も全部SvelteKitに任せられるうえ、DOM構築部分はSvelteなので、lit-htmlと同様に低コストでSSRできる。要は、神ゲー攻略で成功を見たもののうち、技術的にイケてなかった部分とか、自分たちで作らざるをえなかったところを、まるっと置き換えてくれるんです。神ゲー攻略の成功体験はそのままに、しかし実現方法としてはより筋のいいアプローチをということでSvelteKitを採用するということを考えています。
すずけん:なるほど、じゃあだいぶ楽になりましたね。
海老原:いい時代ですね。パブリックベータとはいいながらもしょっちゅう壊れてますけど(笑)そこは気合でついていこうと思っています。
すずけん:理解です。もともと全部自分でやってたのかって読んでる人に思われそうですけど。
海老原:まあ、でもわかってくれる人はたくさんいると思います。Next.jsとか流行っているので、基本的に自分たちでは書かなくていいようにはなっていますけど、軽量にSSRを実現したいとなると話は変わってくる。
すずけん:まとめると、記事データはMySQLでメタデータも含めて管理して、外に出るところは、公開用にビルドされたものを使うっていうのは踏襲しつつ、そのレンダリングの部分とかフロントの部分とかでSvelteKitを使うようにした、というのが構成として変わったところですね。
海老原:あとはAPI周りもですね。神ゲー攻略のときはOpenAPIというか、Protocol Buffersで頑張ってOpenAPIスキーマ定義を生成するということをやっていたわけなんですが、それを捨てまして......。あれだけ大見得切ってブログ書いたのに捨てるっていう(笑)
すずけん:(笑)
海老原:やっぱりエッジケースを叩いてしまっている感じがあって、誰もやっていないというかメジャーな手段ではない。神ゲー攻略でProtocol Buffersを使ってOpenAPIのスキーマ定義を書くために、めっちゃgRPC Gatewayのprotoc-gen-swagger(注: 当時のプラグイン名。現在は protoc-gen-openapiv2)にコントリビュートしまくってどうにか自分たちで使えるようにってやったわけですけど、そうまでしなければいけなかったのか?というのはあって。必要性を感じていたし、実際恩恵はたくさん受けているのでやってよかったと思っているんですけどね。いろいろ考えた結果、管理画面側で利用するAPIだけでですが、GraphQLを採用するようにしました。Protocol BuffersでOpenAPIスキーマ定義を書くという形でやりたかったことは、結局全部GraphQLでまかなえることではあったので。RESTはあんまり捨てたくはないんですけどね、個人的には。でも管理画面用途であればRESTの恩恵はそこまで受けられなくてもいいだろうという判断で、GraphQL全振りにしています。
すずけん:サーバはGoですか?
海老原:そうです。ですのでGraphQL部分はgqlgenで書いてます。
すずけん:えびちゃんのProtocol Buffersの記事はすごく読ませてもらって、これはモダンだなあと、fluctでも試してみたんですね。ただ、結果的にはここまでやらなくていいな、となって、結局OpenAPI定義を直接書いていたんですよ。ただ、それがめっちゃでかくなりすぎて「これ読めなくない?」となってきて、いまGraphQLやり始めていて、……という流れなので実は同じ路線を辿っている。
海老原:GraphQL登場当初というか、GitHubがGraphQLやっていくんだぜと言い始めてからずっと疑問に思っていることがあるんですが、我々ってRESTの恩恵をたくさん受けてきているわけです。RESTはHTTPと相性がいいというか、HTTPの世界に乗っかることが前提となっているので、RESTで作っていればHTTPキャッシュ周りとかの恩恵は自然と受けられるし、ブラウザや各種クライアントのサポート状況も良好だし、デバッグ用ツールも豊富だしと、長年作られてきたエコシステムからの恩恵を受けられる。RESTだったからこその利点は間違いなくあった。で、まあ、(GitHubのGraphQL実装は)たとえばパフォーマンスとかはどうするつもりなんだろうなって思っていたんですよ。GitHubであれば潤沢なマシンリソースによってどうにかするんだろうけど(笑)我々も同じようにできるかというとちょっと疑問なので、GraphQLは完全に管理画面用、使う関係者が限られている環境向けと割り切って利用しています。GraphQLの応答性能であるとかパフォーマンスであるとかは気にしない。
すずけん:むしろ応答性能ではなく、たとえばRPC自体の扱うパラメータの複雑性とか大きさとか、クエリをいろいろ画面によって組み替えたいけど、これ毎回INNER JOIN書くのか?とか。裏では書くかもしれないけどそれをAPIのレイヤーまで持ってきたくないからね。そういうところにはフィットしますよね。
海老原:柔軟な使い方をしたいときにGraphQLはよくて。管理画面とかでいろんな条件だったり、複雑な条件でクエリを投げたりとかが多発する場面ではすごく向くはずです。ほかにも、たとえばプロトタイプ段階のアプリケーションでも効くはずですね。クライアント開発に全集中したいから、とりあえずサーバ側は雑にGraphQLサーバを立ててから、クライアント側でいい感じにこねくりまわして、それっぽいプロトタイプ作ろうというときにはすごくいい。 GraphQLのコミュニティとかがやろうとしていることは、要は、HTTPの世界にイチから新しいプロトコルを作ろうということなわけなので、どうしても発展途上のところはありますよね。ですのでさっき僕が言った、パフォーマンスどうするの? クライアントどうするの? デバッグどうするの? みたいなものっていうのは、プロトコルやエコシステムを盛り上げていく動きのなかでどんどん払拭されていくものかなと。将来的にはどのような用途であってもRESTなんか使わずにGraphQL使えば間違いない、となるかもしれない。ただ、いまのところは、やっぱり長くHTTPの世界とともに生きてきたRESTのほうが、時間をかけてきた分だけ有利なところがありますよね。もっとも、そこは使い分けかなと思うんですけど。パフォーマンス上シビアじゃないところであるとか、GraphQLの恩恵を受けられる場面であればもう全然いいのかなと思っています。
すずけん:同じ意見ですね、わかります。本当にそうですよね。僕らの経験だとgRPCがそうでしたけど、あれも結局全部POSTで投げるって作りなので、これはもはやHTTPなのか? TCPだな? みたいな話も結構していて。GraphQLもPOSTベースだし、HTTPのメソッドってなんだっけみたいなジレンマはすごくありますね。僕らは管理画面をたくさん作りますけど、特定の人だけが使う画面って(広く使われる画面に比べて)複雑度の形が違って、扱うデータが異様にいろいろあるけど、使う人は少ない。GraphQLはちょうどそこにフィットする歯ブラシっていうかね。
海老原:本当にそうですね。そういったわけで管理画面側はGraphQLを使っています、と。あとはエンドユーザ側のAPIですが、神ゲー攻略ではBFFを設けていたんですよ。BFFから(管理画面と共用の)APIサーバを叩いて、そのAPIサーバがCloud Datastoreにある情報を取りにいって、みたいな感じだったんですね。で、SSRとかもする以上BFFの層は必要だったんです。ただ、ふと気がついたことがあって……「APIサーバいらないのでは?」と
すずけん:(笑) 普通にCloud Datastoreに取りにいけばいい?
海老原:要は、Cloud Datastore をAPIサーバ的な役割だとすれば、別にAPIサーバはいらないと気がつきまして。APIサーバいらないよねって言い切るためには、Cloud Datastoreに貯めるデータを十分に加工して整理して、ちゃんと意図通りのレスポンスを返せる状態にするお膳立ては必要なんですが、それさえできていればマジでここにAPIサーバがいる意味ないなと思って(笑)なのでここも変えていますね。新規メディアのほうではBFFから直で(Cloud Datastore の後継プロダクトである)Cloud Firestoreを見にいく。BFFがCloud Firestoreから抽出したデータを(HTML や JSON などの)ユーザフレンドリな形で加工して返すという役割に位置付けています。
すずけん:BFFはエッジサーバで動いているんですか?
海老原:このBFFもSvelteKitの機構を使っていて、SvelteKit自体はエッジサーバで動かすこともできますが、我々はNode.jsサーバを立ててやっていますね。
すずけん:なるほど。
海老原:ここでCloud Firestoreからデータをとってきて、SvelteKitでHTMLを生成する機構とがっちゃんこさせたりとか。記事はMarkdownで書いているので、Markdown パーサをかませたりとかしています。
すずけん:Cloud Firestoreからとるところで、APIサーバがあるとたとえばCloud Firestoreに繋ぐところの権限周りとかもそうだし、BFFに返す前にデータをいじることもできるけど、ないほうがコンポーネントが減るから単純に楽にはなりますよね。
海老原:そうですね。ただ、Cloud FirestoreやBFFに多くの仕事をさせすぎないということには気をつけなきゃいけない。Cloud Firestore上にユーザに公開できない情報は絶対に置かないとか、そういうところは気をつけて設計する必要があると思います。そのあたりさえできていればAPIサーバがやってくれるお膳立ては一切なしで、やりたいことが実現できるようになる。
すずけん:ほほう。言われてみれば確かに。だけど元からAPI叩いている人たちからすれば「マジ? いけるんですか?」となりそう。
海老原:妥協が必要なところかもしれないですね。記事メディアとして神ゲー攻略を運営していくなかでわかってきたこととしては、エンドユーザに秘匿する情報って全然ないんです。(秘匿するべきなのは)本当に内部の編集情報くらいで、基本的には公開可能な情報だけなんです。だから特別な権限管理があまりいらなくて、APIサーバをすっ飛ばしてCloud Firestoreから引っ張ってこられる。みんなが見られる情報だけがCloud Firestoreに載るので、そこそこ雑に扱いやすいし、かつキャッシュもしやすいので効率的に届けやすい。完全に記事メディアだからできることって感じですが、メディアならではの特性に全振りするとここまで単純化できる。
すずけん:いやあ、だいぶアーキテクチャ判断がソリッドにというか、ブラッシュアップされてむしろシンプルになりましたね。
海老原:そうですね。シンプルになったのと、自分たちで作らないようになった(笑)
すずけん:神ゲーの反省点がバチっとアーキテクチャに活かされてますもんね。わ、気がついたら1時間経ってました。いっぱい聞けておもしろかったです。実際に書いてみてどうだった?とかもっと聞きたいところではありますが、今日はここまでですね。
海老原:ありがとうございました。話せて楽しかったです。
すずけん:ありがとうございました。
PR
Lighthouse StudioではEMやエンジニアを積極大募集中です。 hrmos.co hrmos.co
まずはカジュアルにお話してみませんか? hrmos.co