您如何模拟REST中的复杂操作?

时间:2014-01-18 05:38:18

标签: json api rest architecture hateoas

我正在开发一个在线游戏,角色可以对其他对象和角色执行复杂的动作。我正在构建一个REST API,并且在尝试遵循一些最基本的标准时遇到很多麻烦。我知道REST并不总是答案,但由于各种原因,我使用REST是有道理的,因为API的其余部分会适当地使用它。

以下是一些棘手的例子:

GET / characters / bob / items 这将返回Bob携带的一系列项目。

我需要针对这些项目执行各种“操作”,并且我很难将其建模为“资源”。

以下是一些潜在的操作,具体取决于项目的性质: 扔,吃,掉,举行

这很复杂,因为这些“操作”仅适用于某些项目。例如,你不能吃剑。此外,'eat'基本上具有“删除”资源的副作用。使用'throw'也可以'删除'资源。使用'drop'可以将资源“转换”为另一种资源类型。 '投掷'要求我提供'位置'。 “保持”要求我提供哪一只手来容纳物品。那么如何将这些操作建模为资源?它们都不是“相似的”,因为它们各自需要不同的参数并导致完全不同的行为。

目前,我有一个'actions'资源,我将这些任意操作发布到。但这种感觉太过于RPC和非标准化/可发现:

POST / actions / throw {   characterId:5,   itemId:10,   x:100,   y:150 }

2 个答案:

答案 0 :(得分:6)

我尽可能坚持使用资源和GET / POST / PUT / PATCH / DELETE,但基本动词倾向于直接映射到CRUD调用。如果没有其他信息,通常无法映射其他更复杂的操作。

关注资源,我可能会做这样的事情(向资源发布消息):

POST /characters/bob/items/{bombId}?action=throw
POST /characters/bob/items/{foodId}?action=eat
POST /characters/bob/items/{potionId}?action=add&addedItem={ingredientId}

当该操作不适合该项目时返回错误。

答案 1 :(得分:1)

如果我希望资源在保持RESTful的同时“执行复杂的操作”,我会将一个复杂的文档发布到描述我想要发生的事情的资源上。 (复杂文档可以是XML,JSON或任何其他格式。)这与将POST映射到“创建子资源”的更常见模式有些不同,但POST的含义是“do 由身体内容定义的非幂等行动“。这对你所追求的是合理的。

作为HATEOAS发现原则的一部分,当您获取稍后将POST到的资源时,返回的文档的一部分应该说明这些复杂的操作文档是什么以及应该将它们发送到何处。从逻辑上讲,考虑填写表单并提交表单(即使“表单”实际上是JSON文档中的插槽或类似的东西)。