REST API でサーバサイド UI レイヤを切り分けるアーキテクチャ
すこし前だが、Nicholas C. Zakas の記事が話題になっていた。
Node.js and the new web front-end | NCZOnline
Node.jsをサーバサイドのUIレイヤに限定するのか? - ワザノバ | wazanova.jp
ワザノバさんの抄訳から引用すると、
JavaScriptエンジニアはフロントエンドのコントロールはできるが、サーバサイドのUIレイヤはバックエンドエンジニアの領域で、それがフロント(JavaScript)エンジニアとバックエンドエンジニア双方のストレスであった。 Node.jsの登場で、サーバサイドのUIレイヤをサーバサイドのビジネスロジックから分離し、フロントエンジニアはブラウザ & サーバのUIレイヤ、バックエンドエンジニアはサーバサイドのビジネスロジックを担当するという切り分けが可能になった。
バックエンドの UI レイヤーとは、単純にはテンプレートに相当する、サーバサイド MVC の View のことだ。ビジネスロジックに集中したいバックエンドエンジニアとプレゼンテーションに集中したいフロントエンドエンジニア。従来はその境界線がサーバサイド UI レイヤーだった。プレゼンテーションに関するレイヤーなのにサーバ サイドに属しているので、お互いにフラストレーションのもとになる。その解決策としてこの記事が提案しているのが、フロントエンド (ブラウザ) とバックエンドの間に Node.js のサーバを置きバックエンド (ビジネスロジック) とREST API で通信するというアーキテクチャだ。こうすることで従来のサーバサイド UI レイヤーをフロントエンドエンジニアの世界に持ってくることができる。
この記事の隠れた文脈として「Node.js を使えばフロントもバックもすべて JavaScript で書けるようになるよ」という風潮へのアンチテーゼがあるらしい。なんでもかんでも js でやろうとするのではなく、適材適所に利用しようということだ。あるいは既存のシステムを Node.js ベースに置き換える場合でも、このように段階的に移行する方が現実的だろう。至極真っ当な話だが個人的にはもやっとする部分がいくつかある。
ひとつはサーバサイド UI レイヤーは別に Node.js じゃなくてもいいよねということ。もともとの問題意識からするとバックエンドから UI レイヤーを引き剥がせればそれでよいはず。バックエンドのビジネスロジックとは REST API で通信するし、フロントエンドには HTML を返すので、一般的な Web 開発に使われている言語・フレームワークならば技術的にはどれでも問題ないことになる。この記事では「なんでも Node.js にしようとせずこのくらいにしておこうよ」という文脈で Node.js が登場しているのだとは思うが、裏をかえすと言語が JavaScript であるという以外の理由がないと言える。
つぎはパフォーマンス。当然ながらバックエンドと UI レイヤー間の HTTP 通信が増えるのでパフォーマンスは劣化する。記事中ではそれぞれのサーバは近い場所に置かれるはずなので、問題になるほどのパフォーマンス劣化はないはずとされている。しかし今までデータベースの結果を出力するだけだったところが、データを REST API のインタフェースにそって変換、HTTP を介して送信、受信し結果をパース、得られたデータを加工し HTML 出力というステップを余分に踏むことになる。これは 1, 2 桁のオーダーで処理時間が多くなると考えて間違いなさそうだ。
また開発コストも見逃せない。通信をするレイヤーがひとつ増えるので、その分の入力値のバリデーション、データの変換、出力形式に沿ったデータの組み立てと言った処理を余分にする必要がでてくる。いくらバックエンドは REST API を提供するだけで良くてビジネスロジックに専念できると言ってもそうはいかないはずだ。REST API はモデルから取得したデータをそのまま帰すだけでいいはずがなく、やはりそれに合わせた変換が必要になる。また今まではサーバサイドで一度だけやればよかったリクエストのバリデーションをバックエンド、UI レイヤーそれぞれでやる必要がでてくる。トータルでみると確実に開発コストは増えるはずだ。
なんでもかんでも Node.js に置き換えようなどとせず、適材適所に技術を用いるというのは真っ当だし賛成だ。しかしこのアーキテクチャを導入する必然性薄いと感じる。例えばサードパーティの REST API を使って UI を提供するようなサービスの場合はこのアーキテクチャにせざるを得ないが、通常の Web 開発では従来通りのほうがいいような気がする。