我正在开发一种RPG游戏。我想弄清楚 一种很好,干净,RESTful的方式来定义库存API。
广告资源包含多个slots
,例如head
,chest
等(与大多数RPG游戏一样)。
现在我需要定义REST API以将所有项目从插槽X移动到插槽Y.
我没有几点想法:/inventory
/inventory/movement
那样使用CREATE
并使CRUD
成为POST /inventory/movement
。所以它将是PUT /inventory?move_from=A&move_to=B
。这将是CRUD和REST,但感觉非常糟糕。PUT /inventory/:to_slot?from=:from_slot
。这仍然感觉不太好。所以..为此提出了一个干净的CRUD REST解决方案的想法吗?
更新:刚才有另一个:{{1}} - 还不确定。当涉及2时,为什么只对一个插槽采取行动?嗯......呃!
答案 0 :(得分:4)
因为在REST中,您应始终使用资源或资源集合,在这种情况下,我会将“ MOVE ”操作视为REST资源。这可能看起来不正确,因为我们认为' MOVE '是动词而不是名词,但如果界面涵盖高级抽象,这可能是有意义的。在一个暴露用户可用于控制游戏的选项的高级界面中,您可能希望采用“移动选项”,这突然变成名词!
因此我会使用POST动词来移动广告资源中的项目,因为我们会发出请求创建新的“移动”操作。请考虑以下不言自明的例子:
- POST /move/inventory/a/b
- POST /sell/inventory/a
- POST /use/inventory/b
原始CRUD操作中的“ MOVE ”命令通常使用CREATE后跟DELETE实现。但是,如果您在游戏资源上使用原始CRUD操作,我认为您会发现它太低级了。
如果你要从x获取一个项目并将它放在y中,你会在哪里放置检验y是否是有效目的地的验证逻辑?它应该在模型中(界面后面)还是在游戏中?如果它应该在模型中,那么我认为你应该考虑我之前描述的高级方法。另一方面,如果您打算在游戏中(在界面前)处理此逻辑,那么您可以采用原始CRUD方法,如Jan suggested in another answer。
请注意,如果您的RPG将面向网络,则必须在服务器端处理游戏逻辑。在这种情况下,我会寻求将REST接口与提示给用户的控件和选项一对一地映射 - 再次,我会建议上面提出的高级模型。
答案 1 :(得分:2)
维塔利彼得,
不要考虑行动(转移),而是考虑资源和国家转移。以下是我如何按照REST的要求做的事情:
GET /game/inventories/5536 200 Ok Content-Type: application/rpg.inventory+xml <inventory> <slot href="/game/inventories/5536/slot">X</slot> .... </inventory> PUT /game/inventories/5536/slot Content-Type: text/plain (or what you need) "Y" GET /game/inventories/5536 200 Ok Content-Type: application/rpg.inventory+xml <inventory> <slot href="/game/inventories/5536/slot">Y</slot> .... </inventory>
但也可能有其他方式。
扬
答案 2 :(得分:1)
它应该更新域逻辑中的ipotetic项的position_id,或类似的东西不是吗?
所以我认为你把PUT给了现有的项目:
PUT /items/:id?position_id=:position_id
样品:
PUT /items/1?position_id=2
你已经知道“位置来自”,因为它应该已经定义到你的项目模型中了吗?
当然你可以添加/ inventory / namespace如果你想让它更具描述性,那么我建议:
PUT /inventory/items/:id?position_id=:position_id
P.S。请注意参数后的?不是GET参数:)
答案 3 :(得分:1)
因为清单只是字符模型中的哈希值,所以您可以使用自定义访问器来为每个重要的插槽修改哈希值。
从插槽A到B的RESTful移动可能类似于
PUT /inventory with params:
{inventory => {:worn_on_head => nil, :worn_on_left_arm => @item}}
您可以使用验证和回调来简化参数,甚至可以使用访问者本身来确保相同的项目不在多个插槽中。基本上将移动请求的参数缩短为:
PUT /inventory with params:
{:inventory => {:worn_on_left_arm => @item}}
更安全的做法是,如果用户试图装备的物品副本多于他们的副本,则只会抛出验证错误,而不会在更改时替换其他副本。