我在思考如何使RESTFul API更加意图清晰。在各种博客中,我看到的一个常见模式是传统REST API会导致:
封禁玩家 -> POST /players
但如果我改用更有意图表现力的接口,则可以使用:
封禁玩家 -> POST /players/{ playerid }/banPlayer
我感觉第二个更能表现意图。
团队常常反对第二个接口不符合REST风格。
同时,目前我无法放弃RESTful API。
我想听听你的想法。
在Restful API设计中,对于如何将操作(actions)
应用于资源,有两种不同的观点。
您可以在URI中描述要执行的资源操作:
请求URI:
POST /players/{id}/ban
注意:只需使用ban
即可 - 我们已知资源是玩家,它在基本URI中。
您可以在请求正文中包含操作:
请求URI:
POST /players/{id}
请求正文:
{ 'action': 'ban' }
您可以选择其中任意一种方式 - 无论您偏好哪种,都有很多讨论,但最终两种都是正确的。
注意:
我在这里的假设是禁止玩家不仅仅是更新其部分信息,而是涉及到与玩家相关的系统操作(或状态转换)。否则,如果它只是对玩家资源进行更新,则应根据情况使用PATCH或PUT进行处理。
以下是一些参考讨论:
如果您进行一些谷歌搜索,还有更多的讨论...
PATCH
替代 POST
,我会点赞。 - Quality Catalyst既然你要求的是RESTful而不是最佳方式,这是我的想法。
以下是RESTful的URI选项:
/players
/players/{ playerid }/banPlayer
/player-banning
/entities?action=ban_player&method=PUT
/banana
RESTful的方法是纯粹通过超文本来公开下一个可用状态的知识。为了实现REST,您必须使用超文本作为应用程序状态的引擎(HATEOAS)。依赖客户端对URI的了解是依赖于带外知识,这与REST是相反的。
您的资源不需要直接映射到业务对象。如果选择,您可以将用户意图本身表示为资源,例如禁止玩家事件资源。您可以向其POST一些有关要禁止的玩家的信息,随后的GET将提供有关事件的信息。
哦,只是因为REST不关心URI是什么,并不意味着您不应该关心。您只需使用不同的标准来决定什么是最好的。
banPlayer
不是一个实体,所以你不能使用它。我建议使用PUT方法更新你的记录。这里你可以了解更多规则。实际上,关于URIs的第一部分正好适用于你的情况。这篇Google Cloud文章API设计:理解gRPC、OpenAPI和REST以及何时使用它们澄清了REST与RPC之争。REST更适用于面向实体的API,而RPC更适用于面向操作的API(以及CQRS)。具有超媒体控制的最成熟REST级别3仅适用于具有简单状态模型的实体。
首先了解和评估REST对您的情况的好处。许多API是类REST而不是RESTful。OpenAPI实际上是映射到HTTP端点的RPC,但这并不妨碍它被广泛采用。
BAN /players/{playerid} HTTP/3
怎么样? - Darragh