ゲーム開発にREST API が向かない理由は以下の通り。
- あらかじめ仕様の全体を見通すことができない
- 処理もデータも複合されたものを求められる事が多い
- 仕様の変化が激しい
REST
REST の原則は以下の4つがあるらしい。 原典には6つあるとかないとかあるが、本記事の主眼に影響しないので4つで進める。
- Statelessness(ステートレス性)
サーバーはリクエスト間の状態を持たず、リクエストごとに完結する。 - Uniform Interface(統一インターフェース)
HTTPのメソッド、"GET"、"POST"、"PUT"、"DELETE" で操作する。 - Addressability(アドレス可能性)
リソースをURIで一意的に表現する。 - Connectedness(接続性)
情報の内部に別の情報へのリンクを含める。
リソースをURIで一意に識別できるから、関連する情報をリンク(URI)でポイントできるってことっぽい。
REST の特性
続いてRESTの特性をどう見るか。
RESTはリソース設計がすべてと言っても過言ではない。データをどう分類するかだ。 分類されたデータ、つまりリソースに対してCRUDする。
リソース定義があってそれに対するCRUDが提供されるだけ。
シンプル、だがシンプル故にそこには「特定のリソースを操作する」以外の処理が入り込むのが難しく、
複雑なビジネスロジックや関連する処理、関連するリソースの操作などの処理を含めるのが憚られる。
RESTの設計とはDBのテーブル設計であり、REST APIはデータストアのフロントドアと見ることができる。
向かない理由
DB設計の観点から
DB設計は、管理すべき情報を洗い出してデータモデルとしてモデリング(設計)する。
先に洗い出すため全体が見通せる状態であり、だからこそモデリングができる。
DBのモデル(テーブル)は、一度決めたら変更が効かない。
同様にRESTのリソースも一度決めたら変更しづらい。
そして、ゲーム開発では未来の仕様はまったく未知数である。過去に決めたものさえ確度は定かではない。
仕様の変化により、必要なデータが増えたり、複雑なことが必要になったり、リソースの再設計がしたくなるような場面は多い。
RESTの特性に対してマッチしていない。
これがゲーム開発に向いていない一番大きな理由だ。
クラサバ設計の観点から
クライアントとサーバーサイドのアーキテクチャの設計では、 大前提として、ドメインと呼ぶような主要な処理をサーバーサイドに置くか、クライアントに置くか2つに分かれる。
先に説明したようにRESTはCRUD以外の処理を持たせにくいため、前者には向いていない。
処理はクライアント、サーバーはデータストアと割り切った構成にのみ向いていると言える。
だがしかし、ゲームなどのtoCの領域ではサーバーでしか情報を吸い上げることはできないし、チートとの戦いもある。サーバーで処理したいことは往々にして多い。
外部向けAPI
第三者、外部に向けたAPIの設計には向いてる可能性はある。
そもそも複合的で複雑な処理を持つAPIを提供しないだろうし、APIの仕様を変更することが困難なためあらかじめ念入りに設計することになる。
上手く設計できれば、APIが伝わりやすくもなるだろう。
RPCという選択肢
REST以外に何があるかと言えば、RPC(remote procedure call)となる。遠隔プロシージャ呼び出し。
要はメソッドなので、操作があってインターフェイスが決まる。RESTに比べ自由度が高い。
一見するとインゲームにはRPC、アウトゲームにはRESTが向いてるようにも思える。
しかし、DB設計でも話したように、ゲーム開発はとにかく仕様が不安定なのだ。
その点において、インゲームでもアウトゲームでも、柔軟性があるRPCの方が向いているだろう。
クライアントのドメイン
最後にポエムのポエムのような話、クライアントのドメインについて。
クラサバの設計でドメインと呼ぶような主要な処理をどっちに置くかと言う話をした。
クライアントに主要な処理を置く場合、それはドメインと呼ぶに値する何かとなるだろう。
一方で、サーバーに主要な処理を置く場合、サーバーにはドメインが存在する。
この時クライアントにもドメインが必要なのかと言うとそうではないと考えている。
サーバーサイドにメイン処理があるようなシステムのクライアントは、基本的にサーバーからの情報を取得してその情報を元にした再生マシンと化す。
ここでクライアントに必要になるのは、状態とその状態を入出力(UI)に同期させる機構である。
この処理群をドメインと呼ぶには疑問が残る。
サーバーにドメインがあるようなシステムにおいて、クライアントの設計でドメインを探そうとすると沼に落ちるだろう。
クライアント、サーバーそれぞれに同じ処理を持たせる、またはドメインを分離するみたいな設計をする場合はこの限りではないが。