以RESTful方式表示移动资源



我试图通过构建一个基本的纸牌游戏web服务来学习如何构建一个RESTful web服务。当我试图模拟玩家如何从牌组中抽牌时,我陷入了困境。我有/deck资源和/cards资源。随之而来的是两个问题:

1。什么资源路径应该为我抽下一张牌?使用GET: /decks/{deckId}似乎是错误的,因为它可能会为我返回整个甲板。作为GET: /decks/{deckId}/topcard访问资源是否有意义?

2。假设GET: /decks/{deckId}/topcard是有意义的,我知道我不应该使用GET来实际从牌组顶部移除卡片,因为该操作应该是幂等的。在这种情况下,我们可以这样做:

GET: /decks/{deckId}/topcard ->返回topcardId(不返回卡的实际值)。不希望客户端作弊)

POST: /hands/{handId}/cards/{topcardId} ->将先前检索的topCardId添加到玩家手中。将牌组中的下一张牌设置为顶卡资源。返回第一张牌的实际值。

我有一个问题的部分是,在内部修改/decks/.../topcard资源作为向其他/hands/.../cards资源请求POST的副作用似乎是错误的。这是休息吗?还有其他选择吗?

我试图学习如何通过构建一个基本的纸牌游戏web服务来构建一个RESTful web服务。当我试图模拟玩家如何从牌组中抽牌时,我陷入了困境。我有/deck资源和/cards资源。

简短版:你缺少一个经销商资源。

你向发牌者资源发布一条消息,成功处理该消息的副作用是数据模型中的牌组状态和玩家的手牌得到更新,发牌者资源将客户端重定向到一个新的表示…只要符合你的规定就行。这可能是他们手中的新牌,也可能是发给他们的两张牌的代表,或者其他东西。

Jim Webber在他的关于rest式系统的领域驱动设计的演讲中进行了详细介绍。从较高的层次来看:REST的重点在于客户端代码和底层服务可以独立发展(浏览器版本与服务器版本分离),因为即使底层实现需要更改,API层也能提供稳定性。

这意味着如果您将资源标识符的拼写与域模型中的实体相耦合,那么您就违反了封装。在REST模型中,您操作资源,作为副作用,底层数据模型发生了有趣的事情。

尝试只用四个方法来操作你的数据实体,事实是非常痛苦的。REST中的逃生舱口是允许您拥有尽可能多的资源。

工作(例如:向域模型发出命令)是管理资源的副作用。换句话说,这些资源是反腐败层的一部分。您应该期望在集成域中拥有比在业务域中拥有业务对象多得多的资源。

简而言之,如果您需要扩展api以支持新行为,只需创建新资源。它们不需要匹配数据模型中的任何内容。

现在,HTTP是无状态的,因此您需要考虑服务器需要哪些信息来明确地转换请求。在"发牌卡"的例子中,这可能就像清楚地识别正确的牌组和正确的玩家一样简单。您主要有三种选择:您可以将该信息放入标识符路径的段中,放入标识符的查询参数中,或放入消息体中(即表单变量)。数据放到哪里很大程度上取决于你使用的资源框架和你的本地设计准则。

POST /deck/{deckId}/dealer
cards=2&toPlayer={playerId}

是一个选项。

我有问题的部分是修改/甲板/……似乎是错误的。/topcard资源内部作为一个副作用请求POST到其他/手/…/卡的资源。这是休息吗?

是的——一直都在发生。考虑一个博客—您推送了一个新条目,并且对条目、提要和其他条目进行了更改,现在将新条目列为最近的文章....

当你决定缓存策略时,你需要考虑到这一点;中间缓存将知道您发送给一个资源的消息使一堆其他缓存条目无效。

我想我不太明白的部分是这与使用HTTP进行RPC有什么不同。

一般来说,使REST不是RPC的原因是中间组件(缓存、反向代理)可以主动参与请求/响应交换。因为POST(以及类似的PATCH)既不安全也不幂等,所以您肯定会得到类似RPC的东西。如果您使用PUT语义,而不是PATCH,它会稍微好一点。

但是,请注意,即使使用POST和PATCH,中介体仍然可以理解消息类型,而无需了解目标资源的任何信息。

https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html sec9.5

当我读到下级这个词时,它让我觉得我应该期望从这个中创建一个实际的资源。

不足为奇。注意,语言在RFC 7231中被改变了,短语"下级资源";不再用于该上下文中。

我认为你的方法是对的。通过POST,您可以更改资源的状态,这对于"rest-full"服务是有效的。

最新更新