Isomorphic Javascriptのジレンマ

@axrossがIsomorphic Javascriptを実現すべく、社内にNode.jsを啓蒙する発表の場に僕はいた。僕は2ヶ月前までWebフロントエンドエンジニアであり、今はサーバーサイドエンジニアをやっている。その2つの立場から@axrossの発表を聞いて、自分の考えを書いておく。

社内事情的な側面もあるので、この記事を読んでからの方が理解しやすいと思います。

フロントエンド側の動機

僕もIsomorphic Javascriptの未来を見たい。@axrossが社内でこのようなきっかけをつくってくれたのは嬉しい。これを機にフロントエンドとサーバーサイドが歩み寄るといい。

サーバーとAPIとの統合時に、型の違いなどの衝突が起こることがある。レスポンスのJSONの中で、数値であるべき値が文字列であったり、もっと酷いと空の配列がnullになっていたりする。PHP連想配列SQLドライバの問題なんだろうけど、これがかなりの頻度で起きる。その都度サーバーサイドの人に修正してもらうのだが、コミュニケーションコストをともなう。

コミュニケーションをあきらめてしまう人もいる。コードレビューのとき異常な量のバリデーションやキャストを見つけたとき指摘をすると、そのような理由を聞く。この問題がより深刻なのはWebよりもネイティブクライアントで、キャストエラーでアプリがクラッシュする。それを回避するためにネイティブ側でレスポンスの形式が正しいかどうかテストを書いている人がいる。(本来それはサーバーサイドが書くべき受け入れテストなのにね。生産性の高いことを理由にPHPを採用したのに、生産性の低いネイティブコードでテスト書いてては意味ないだろ!)

これは数ある問題の1つでしかない。

Isomorphicな開発を採用できれば、モデルやバリデーション、ユニットテストなどを共有できる。書くコードを共有でき生産性が上げられるのみでなく、コミュニケーションコストも大幅に下がるだろう。axrossもこのようなフラストレーションのすえにisomorphismの提案に踏み切ったのだろう。

ただし僕らがIsomorphic Javascriptを実現するまでには、まだ長い道のりが待っている。

Isomorphic Javascriptの前に

@axrossの発表の質疑で、社内ですでにNode.jsを使ってチャットサービスをやっているチームからNode.jsの欠点の指摘があった。

  • 安全なデプロイメントの構築が難しい
  • APIの更新が激しく、バージョンを上げにくい

ただしこれらはNode.jsへの直接的な批判ではなくて、その根底に社内の柔軟性のないインフラに問題があると僕は思う。オンプレミスのサーバーを使っており、1台の性能が非常に高い。なので複数のサービスが1つの物理マシンに乗っていたりする。これではNode.jsのバージョンを上げることは危険だし、デプロイもリロードに頼るしかない。

この問題はまさに今僕が取り組んでいる問題だ。今僕はScalaのAkkaを使って開発しているのだけど、Node.jsと同じくシングルプロセスでイベントループが回っているのでリロードは避けたい。なのでBlue-Green Deploymentができるようにしている。これが当たり前になればNode.jsを導入する障壁も下げられるだろう。

他にも冒頭で紹介したAPIの型が安定しない問題に関しては、通信部分のモデル層をサーバー側からクライアント側に自動生成することで、クライアントサイドのモデル実装のコストや統合のコストは下げられる。両者が異なった言語でもこの手法は適用できる。

要はIsomorphic Javascriptのような両領域が高度に統合された難しいものでなくても、単純にお互いが開発しやすいようにしてあげればいいだけで問題が解決することもある。Isomorphic Javascriptの前にやれることはたくさんある。

もちろんIsomorphic Javascriptの前にやらなければならないこともある。社内ではTDDやコードレビューは、サーバーサイドもフロントエンドもまだ十分にできていない。これができていない状態でIsomorphic Javascriptに踏み込んでも、十分な恩恵は受けられないし、僕たちが見たかった未来とは違う結末に陥る危険性がある。

Isomorphic Javascriptのジレンマ

今所属している会社ではインフラを始めもろもろの問題があり、isomorphicな開発を実現するまでに解決すべきことがいくつもある。

これらの問題を見て「それは君の会社のサーバーサイドやインフラエンジニアがやることをやってないからだね。」と言うのは待ってほしい。僕もそう思いたい。しかしそう思ったときに、自身の矛盾にぶつかる。

Isomorphic Javascriptは究極的にサーバーサイドとフロントエンドの境界をなくしていくというものだ。Isomorphic Javascriptを実現したいフロントエンドエンジニアが「それはサーバーサイドの仕事」と境界を作ると議論は進まなくなる。Isomorphic Javascriptができないのは社内のサーバーサイドのせいだと言ってしまうと、自己矛盾に陥ることになるのだ。

この「isomorphismに従って相手の領域との境界を取り払ったら自分の範疇の問題が急激に増えて手に負えなくなる。だからといってそれをその領域の専門家に任せるとisomorphismに反する」問題をIsomorphic Javascriptのジレンマと呼ぼう。

Isomorphic Javascriptを実現するには

サーバーサイドにとってみればJavascriptという言語は数ある選択肢の1つでしかない。一方でフロントエンドではAltJSとJavascriptしか選択肢がない。さらにサーバーサイドレンダリングをしようとすると、サーバー側にJavascript処理系が必要になる。Isomorphic Javascriptを提案するということは、フロントエンドが解決できる問題が増える一方で、サーバーサイドの選択肢を奪うことになる。

このようにお互いの利害が非対称なので、フロントエンド側の提案でIsomorphic Javascriptを実践するなら、フロントエンド側はその利点を説明した上で、サーバーサイド側も含めた開発にある程度責任を持たなければならない。フロントエンド側はフロントエンドに加えてサーバーサイド側の知識も持っていないといけないということになる。このハードルはかなり高い。

Isomorphic Javascriptな開発を実現するまず第一歩として、サーバーサイド側の数ある選択肢から技術を選ぶ際に、フロントエンドの意見を取り入れる余地をつくらなければならない。実際うちのフロントエンドのメンバーが最も怒っているのはこの部分だ。つまり両者の統合領域が広がりつつある今、サーバーサイドの技術を決める際にフロントエンドが意見する機会すら与えられていないことだ。最終的にそれがPHPだろうがNode.jsだろうが、お互いに選定理由に合意していれば衝突はおきないだろう。

Webフロントエンドの未来

Isomorphic Javascriptが描く未来では、サーバーサイドとフロントエンドの境界がなくなる。これを押し進めるもう1つの流れにExtensible Webがある。Extensible Webによって低レベルAPIがブラウザにやってくる。極論ブラウザでもそれらの低レベルAPIを使ってサーバーサイド同じぐらい高度なことができてしまうわけだ。

この2つの大きな流れの帰結として、フロントエンドエンジニアもサーバーサイドの知識が必要ということになる。

で実際問題として、これができるフロントエンドエンジニアってどれぐらいいるのだろうと疑問に思う。

例えば今回の社内の問題では、Node.jsを導入しやすくするにはインフラまで手を入れる必要があった。この問題につい最近までWebフロントエンドエンジニアだった僕が取り組んだのだけど、やっぱり難しい。幸い同じ問題意識をもっていた社内のインフラエンジニアが協力してくれたからできたけど。今後フロントエンドだけでは解決できない問題がたくさん出てくると思う。フロントエンドエンジニアの定義も変わるだろう。

未来のことは誰にもわからない。だから僕は今僕ができることをサーバーサイドからやっていく。@axrossのような開拓者が突き進めるように、そして自分がフロントエンドエンジニアに戻ったときに快適にIsomorphic Javascriptに取り組めるように、荒野状態の社内のサーバーサイドの領域を耕しておく。