RESTful API设计和CQRS

时间:2018-01-07 19:37:13

标签: rest cqrs

我在考虑如何使RESTFul API更具意图揭示。我在各种博客上看到的常见模式是传统的REST API导致

禁止玩家 - > POST /players.

但我要更改为更具意图的界面,我可以使用

禁止玩家 - > POST /players/{ playerid }/banPlayer

我认为第二个更有意图揭示。

我从团队得到的共同反对意见是,第二个不符合启动REST风格。

目前我也无法摆脱RESTful API。

我想听听你对此的看法。

7 个答案:

答案 0 :(得分:2)

你提到的两个例子都不是适当的REST apis。

更实际的方法就是说你有一个“玩家”。资源。该播放器资源可能具有属性banned,这是一个布尔值。

要将banned属性设置为true,您可以发出如下请求:

PUT /players/1234

让请求正文包含禁用属性的新值。

答案 1 :(得分:1)

根据REST API方法,您需要在URI中使用您的实体,因此,由于banPlayer不是实体,因此您无法使用它。 我建议用PUT方法更新你的记录。 Here您可以阅读有关规则的更多信息。实际上,关于 URI 的第一部分就是你的情况。

答案 2 :(得分:1)

使用Restful API设计,有两种思路可以围绕如何将actions应用于资源。

  1. 您描述了对Uri中的资源采取的行动:

    请求Uri:
    POST /players/{id}/ban

    注意:只需使用ban - 我们已经知道资源是一个玩家,它在基础Uri中。

  2. 您可以在请求正文中执行操作:

    请求Uri:
    POST /players/{id}

    请求正文:
    { 'action': 'ban' }

  3. 你可以选择任何一种方式 - 无论你喜欢什么,两者都有很多讨论,但最终都是正确的。

    注意:

    我在这里假设禁止播放器不仅仅是更新播放器的一部分,而是与播放器相关的系统操作(或状态转换)。否则,如果它只是对播放器资源的更新,则应根据需要使用PATCH或PUT进行处理。

    一些讨论供参考:

    如果你做一些谷歌搜索还有更多...

答案 3 :(得分:1)

  

我从团队得到的共同反对意见是,第二个不符合启动REST风格。

简单的答案是:API的一致性有价值,无论是否REST。所以“这不是我们在这里做的事情”将会胜过“但REST说”。

API中URI的拼写很像代码中方法名称的拼写。对于不同的风格,有很多不同的论点,但“本地约定”本身就是一个强有力的论据。

这就是说 - REST并不关心您用于标识符的拼写。

这就是Fielding had to say in 2008

  

REST API应该花费几乎所有的描述性工作来定义用于表示资源和驱动应用程序状态的媒体类型,或者为现有标准媒体定义扩展关系名称和/或启用超文本的标记类型。在媒体类型的处理规则的范围内(并且在大多数情况下,已经由现有媒体类型定义)应该完全定义用于描述在感兴趣的URI上使用什么方法的任何努力。 [失败在这里意味着带外信息驱动交互而不是超文本。]

带内将在资源表示中包含URI - 将其放入HTML文档中表单的描述中。带外正在记录URI,并希望人们用它来做正确的事情。

注意:人类可读的URI或记录应该使用的URI没有任何问题。但请注意,即使编写浏览器的人没有阅读stack overflow's API documentation - 这就是REST,你也可以将问题发布到stackoverflow。

答案 4 :(得分:0)

长话短说:它不应该是强制性的意图揭示,但如果你想在这个API的外观上添加一些DDD那么它就不会阻止你这样做

根据HATEOAS Web API的RESTful约束(此约束是REST的“统一接口”功能的重要组成部分,如Roy Fielding的博士论文中所定义),您的API的软件客户端不应该关心URL。每个可能的和允许的操作都应该包含在响应中,并带有相应的link relation和URI。通过这种方式,您只需要对链接关系进行硬编码。

但是,此约束不会阻止您为尝试理解整体架构的 Human 客户端提供更多意图。我建议您选择此路径,因为人类用户至少与他们编写的软件一样重要。

Roy Fielding在his blog post上写到了这一点。

答案 5 :(得分:0)

既然你要求RESTful方式不是最好的方式,那么这就是我的想法。

您的RESTful URI选项包括:

  • /players
  • /players/{ playerid }/banPlayer
  • /player-banning
  • /entities?action=ban_player&method=PUT
  • /banana
  • 其他任何事情,REST都没有规定你的URI应该是什么样的

RESTful方法是纯粹通过超文本公开下一个可用状态的知识。要执行REST,必须使用超文本作为应用程序状态引擎(HATEOAS)。依赖客户端对URI的了解取决于带外知识,这与REST是对立的。

您的资源无需直接映射到您的业务对象。如果您选择,您可以将用户意图本身表示为资源,例如被禁止的玩家活动资源。你可以通过一些关于哪个玩家禁止的信息来发布它,随后的GET将提供有关该事件的信息。

哦,只是因为REST并不关心你的URI是什么,并不意味着你不应该这样做。您只需使用不同的标准来决定什么是最好的。

答案 6 :(得分:0)

这篇Google Cloud文章API design: Understanding gRPC, OpenAPI and REST and when to use them阐明了REST与RPC的争论。 REST与以实体为中心的API更相关,而RPC与以动作为中心的API(和CQRS)更相关。具有超媒体控件的最成熟的REST level 3仅适用于具有简单状态模型的实体。

首先了解并评估REST对您的案例的好处。许多API都是REST风格的,而不是RESTful风格的。 OpenAPI实际上是RPC映射到HTTP端点和HTTP端点,但这并不妨碍它被广泛采用。