ターンベースのゲーム サーバーを RESTful API としてどのようにモデル化しますか? たとえば、チェス サーバーでは、同じ API の別のクライアントに対してチェスのゲームをプレイできます。他のクライアントとゲームを要求して交渉する何らかの方法と、ゲームの個々の動きをプレイする何らかの方法が必要になります。
これは REST (RESTful) API の良い候補ですか? それとも、これを別の方法でモデル化する必要がありますか?
私は次のようなことを考えています:
/game/<gameID>/move/<moveID>
基本的なリソースに関する限り。「他のプレイヤーはもう動いたの?」の扱い方がわかりません。しかし、アイデア。私は、移動が再生されるまでGETリクエストブロックを使用することを考えました。つまり、クライアントは移動の座標をに配置します。
/game/13/move/1
そして、GETします
/game/13/move/2
サーバーはすぐには応答しませんが、他のプレーヤーが移動するまで(つまり、その場所にPUTするまで)接続を開いたままにします。これは中島が「彗星風」と呼んでいるものですか?
チャーリー、あなたがその順番の「トークン」が何を意味するのかよくわかりません。これは、ポーリングや接続のブロックを必要とせずに同じ問題を解決しますか?
プレーヤーIDの場合、それらをURLの一部のリソースとしてモデル化することは意味がありますか?私は単にHTTPユーザー認証(ユーザー/パスがすべてのリクエストの一部として送信される)を使用することを計画していました。認証なしでもほとんどのリソースを取得できますが、たとえば、
PUT /game/13/move/2
そのゲームの正しいクレデンシャルがない場合は、許可拒否エラーが発生します。
わかりました。REST の基本的な考え方は、状態を転送するということです。サーバーに「セッション状態」をほとんどまたはまったく持たないようにしたい。そのため、Comet が行っているセッション状態とキープアライブを使用したくないでしょう。しかし、メール対戦ゲームの例を考えてみましょう。2 人ともボードのコピーを持っていて、手札を交換します。郵便局はゲームについて知りません。
さて、これについて考えるにつれて、これが私の心の中で成長していることを認めます-実際、私はこの質問に基づいて記事を書くかもしれません-しかし、いくつかの物語としてのアイデアは次のとおりです。
サーバーの状態に関しては何も必要ありません --- 移動などを追跡することでこれを拡張したいかもしれませんが、ランキングのために - 誰が移動する権利を持っているかという問題は、ボード ページ: 権利がある場合は、移動を入力するためのフォームがあります。フォームのリターンを送信すると、応答は移動を入力するためのスロットがないページを返します。
「トークン」とは、「私の動き」/「あなたの動き」という状態の 1 ビットの任意の表現を意味します。
必要なリソースは
モデル化しようとしているリソースは何ですか? あなた、対戦相手、特定のゲーム (セッション、インスタンス)、およびゲーム ボードの状態です。したがって、次のようなもので始まります
/game
/game/gameID/gamer/gamerID
/game/gameID/board
InfoQに優れた紹介/概要があります。
私は、REST がそのようなアプリケーションに適しているとは思いません。必要な変換と操作 (移動、移動履歴の表示、元に戻す、提案の取得、回転通知) は、REST のリソースの概念にうまく対応していません。(Scrabble や Monopoly などのより複雑なターンベースのゲームの RESTful API がどのように見えるかを考えると、問題はおそらくより明白になります。)
賢明な REST API は、ポータブル ゲーム記法をやり取りするステートフル プロトコルなど、RESTful でないもののラッパーになる可能性が高いと思います。
ありがとう、チャーリー。スキームで相手の動きをどのように通知するかはまだよくわかりません。もちろん、誰が移動する権利を持っているかという問題は、ボード リソースから、または移動する順番を明示的に示す別のリソースを使用して、簡単に計算できます。しかし、クライアントはこのリソースが変更されたことをどうやって知るのでしょうか? 何かが変更されたことに気付くまで、以前の状態を記憶して、単純に継続的にポーリングする必要がありますか? ポスト オフィス モデルでは、ポスト オフィスがメッセージをクライアント (メールボックス) に「プッシュ」しますが、これは HTTP では不可能です。
これはより一般的な質問の一部だと思います:変更や修正を監視したいRESTリソースがある場合、それを行う最善の方法は何ですか? そして、これをクライアントにとってより簡単にするためにサーバーができることはありますか?
それ自体が興味深いと思うので、実際には別の質問として投稿すると思います。
編集して追加: REST リソースの変更を監視する RESTful な方法とは?
Planet.jabberの開発者の 1 人は、オンライン チェス コミュニティであるChessparkに参加しています。Jabber/XMPP を広範囲に使用しています。私が間違っていなければ、これらは件名に関する彼の投稿です.
XMPP はインスタント メッセージング プロトコルであり、大まかに言えば小さな XML メッセージ交換に基づいています。Javascriptを含むほとんどの言語用のライブラリがあります。ただし、それがあなたの問題に適合するかどうかはわかりません。
それで、あなたの考えは、アクションをファーストクラスのオブジェクトにする代わりに、各動きはゲーム自体の更新として扱われるだろうということですか?これは確かに別の方法ですが、いくつかの理由から、アクションオブジェクトを独自のファーストクラスエンティティに分割したいと思います。最大の理由は、それがよりテスト可能であると私が信じていることです。移動が有効であるかどうかは、ボードが常に有効な状態にあることを心配する必要がなく、アクションオブジェクトに存在する可能性があります。確かに、どちらのアプローチが必要かはわかりませんが、これは私にとっては気分が良いです。
YAGNIを介して完全に反論できるもう1つの理由は、ファーストクラスアクションオブジェクトが移動の履歴を提供することです。おそらく興味深いですが、要件がない限り、論点です。
RESTful にモデル化できると思います。彗星のようなソリューションが必要になるか、AJAX を介して比較的短い間隔でサーバーをポーリングする必要があるため、実装はより困難になります。
RESTful インターフェースをどのように公開するかという点では、座標、それらの座標を占めることができるピース、およびそれらの座標を変更するアクションを備えたプレイボードが必要だと思います。
プレーヤーが手を動かすと、新しいアクションが作成されます。許可されていることを確認した後、ゲームのステータスを更新し、UI を更新するために必要な応答をレンダリングします。
それが基本的に私がそれをモデル化する方法です。ただし、実装側は、ここでのより大きな難しさだと思います。
中島さん、そんなに複雑ではないと思います。たとえば JSON で、ボードの位置、移動、および次の移動のトークンを含むデータを渡します。メールで遊んでいるようなものです。
ゲームに行って相手を探すところから始まるので、
/game/
待っている人のリストを表示します。入って待っている人がいない場合は、ゲーム ID を取得します。それ以外の場合は、待っている人を選び、その人が持っているゲーム ID を取得します。
/game/gameID
ボードを表示します。誰が白をプレイするかの決定を設定するために何かが必要です。それは演習として残します。GET 操作はボードを提供するため、POST は移動を送信します。移動していない場合は、エラーが発生します。次の GET で結果を取得します。
地獄、このモデルでは、ゲーマー ID すら使用していません。