webフロントエンドからwebAPIを呼び出すのをwrapするアレの名前

twitterに書いたやつ再掲+加筆。

Webフロントエンド、というかSPAの設計で、単なるwebAPIラッパーに対して「Repository」と名付けるケースが散見されるけど、ぼくはあれあまり好きではないです。というのも、Repositoryという名前がついてると、集約的なもの、それが言い過ぎならいわゆるEntity、それも言い過ぎならひとかたまりのデータを保存、取得するだけの責務のように思えるからです。けど、実際の「Repository」を見てみると、取得されるのは画面の仕様にベッタリなJSONだったり、更新系としてもなんちゃらidとパラメータを渡すようなIFになってることが多いですよね。画面の仕様にベッタリなJSONが返ってくるようになってたり、idとパラメータ渡すだけだったりするのは、多くの場合考えることが少なくて済むし通信量も減る良いプラクティスだと思うので、それ自体は問題ではないと思っています。ただ、Repository な責務でないものにRepositoryという名前をつけるのがあまり好きではない、という話です。

とはいえ、これは「好き嫌い」の問題なので、「このプロジェクトではそういう名前なんだよ」というのがチーム内で合意が取れてればそれはそれで、とも思います。ただ誤解は産みやすいからそこんとこコミュニケーションしっかりとりたいですね。

ちなみに、じゃあぼくがそれをなんて名前にするかですが、ぼくはよく「Gateway」という名前を使います。サーバーはフロントのSPAと異なるシステムなので、その境界をまたいだ処理を行う窓口だよ、という意味でのGateway

以上がtwitterでしゃべったことです。以下は補足です。

いま扱ってるものが(たとえば)SessionStorageに保存しているものなのかネットワーク越しにあるシステムに保存されているものなのかを意識したくない、だからRepositoryという名前を使うんだ、という話もあると思うのですが、多くの場合APIサーバーは「たんにデータの出し入れ」じゃなくて、たとえば参照系のAPIなら集計をしたり、更新系のAPIなら複雑なロジックを実行したあとになにかを保存したり、それどころか別のシステムを呼び出して結果として誰かに通知が飛んだりなどが行われるかと思います。それと同等のことをローカルでできるでしょうか?もしできないとしたら、ネットワーク越しにあるシステムの呼び出しとローカルのストレージの読み書きを意識しない、なんてこと意味があるのでしょうか?また、仮にローカルでもおなじこと(集計やら複雑なロジックを伴ったデータの更新)ができるとして、その場合それって「Repository」なのでしょうか。Repositoryと言うには賢すぎる気がしますね。

もちろん、APIが完全にリソース志向で、ロジックはほとんどローカルにあります、みたいなアプリケーションなのであれば、そのAPIのwrapperをRepositoryとして扱うことが可能でしょう。たとえばあまりユーザー同士のインタラクションがなくて、クラウドは単なるデータ置き場である、みたいなアプリケーションの場合とかは、そういうやり方が適するかもしれません。また、ユーザごとの設定値のようなものについては、たしかにローカルに保存しているのかネットワーク越しのシステムに保存しているのかは意識したくないかもしれませんね。こういったものについては、自信をもってRepositoryとすればいいと思います。

そう考えると、もしかするとひとつのSPAの中で、このAPI呼び出しはGatewayという名前、あのAPI呼び出しはRepositoryという名前、ということが起こるかもしれません。これは良いことでしょうか悪いことでしょうか。ぼくは「良いこと」だと思います。一貫性がない? けどそもそも、実装(それがローカル保存なのかネットワーク越しのシステム保存なのか)を意識したくないから、意識しなくていい名前をつけよう、という話だったはずです。そう考えると、「別のシステムに対する処理の移譲(その別のシステムがどこにあるかは意識しない)」についてはGateway、「データの保存と読み込み」についてはRepositoryを使う、というのはかなり筋が良いようにぼくには思えます。

というわけで、「webフロントエンドからwebAPIを呼び出すのをwrapするアレの名前」について考えてみました。みなさんのご意見もぜひ聞かせてください。