RESTful API:我应该在哪里编写工作流程?

时间:2014-04-16 15:56:30

标签: api rest architecture workflow restful-architecture

我正在开发一个RESTful API。这是我的第一个API,也是我的第一个非常大的编码项目。因此,我还在学习很多有关建筑等方面的知识。

目前,我在以下层中设置了api:

  • HTTP Layer
  • 资源层
  • 域模型/业务逻辑层
  • 数据访问/存储库层
  • 持久存储/数据库层

我目前遇到的问题是我需要在哪里放置工作流对象/经理?按工作流程,我的意思是评估最终用户下一步所需的代码。例如,电子商务工作流程。用户将项目添加到购物篮,然后签出,然后填写个人详细信息,然后付款。工作流程将负责决定接下来的步骤,以及不允许的步骤。例如,用户不能通过在输入个人详细信息之前尝试付款来导致API中的错误(可能他们回想起付款的URI并尝试跳过一个步骤)。工作流程将检查所有先前的步骤是否已完成,如果没有,则不允许付款。

目前,我的工作流逻辑位于资源层中。我正在使用超媒体链接向用户呈现工作流程,例如提供“下一步”链接。我遇到的问题是资源层是顶级层,并且与表示更加一致。我觉得需要对底层域模型有太多了解才能有效地评估工作流,即需要知道它必须在允许付款之前检查personal_detail的实体。

这使我认为工作流属于域模型。这确实更有意义,因为真正的工作流是业务逻辑的一部分,因此我认为最好放在域层中。毕竟,用其他东西替换资源层,你仍然需要基础工作流。

但现在的问题是,工作流需要知道几个域对象才能完成其逻辑。它现在感觉是对的,它可能会在自己的层中?在资源和域层之间?

  • HTTP Layer
  • 资源层
  • 工作流程层
  • 域模型/业务逻辑层
  • 数据访问/存储库层
  • 持久存储/数据库层

我只是想知道是否有人对此有任何其他意见或想法?正如我所说,我没有过去的应用经验来了解应该放置工作流程的位置。我真的只是第一次学习这个,所以想要确保我正确的方式。

非常感谢链接到涵盖此内容的文章或博客。喜欢阅读不同的实现。

修改

为了澄清,我发布HATEOAS允许客户端浏览“工作流程”,但我的API中必须有一些知道要显示的链接,即它确实定义了允许的工作流程。它在资源中显示与工作流相关的链接,但另外它验证请求与工作流同步。虽然我同意客户可能只会遵循资源中提供的链接,但是休息的危险(和美)是它的URI驱动,所以没有什么可以阻止恶作剧客户试图通过以下方式“跳过”工作流程对URI进行有根据的猜测。 API需要发现这一点并返回302响应。

4 个答案:

答案 0 :(得分:3)

这个问题的答案让我得到了相当多的研究,但基本上是“工作流程”和#39;部分与REST完全无关,而与应用层有关。

我的系统的应用程序逻辑与REST API紧密耦合。我通过重构来减少耦合来解决我的问题,现在工作流程仍然存在于应用程序的上下文中

答案 1 :(得分:1)

REST鼓励您根据已建立的动词集(GET,POST,PUT,DELETE)创建名词(用户,产品,购物车)的词汇表。如果您遵守此规则,那么在您的示例中,工作流实际上是由用户与您的站点进行的交互集定义的。这是用户使用您的应用程序的方式,它实际上是由UI定义的。您的REST服务应该对无效的状态请求作出适当的反应,例如尝试使用空的购物车结帐,但UI也可以使用脚本阻止此类请求,这是REST的可选特性。

例如,向用户显示产品的UI也可能会显示一个链接,允许用户将该产品添加到他们的购物车(POST shoppingcart / {productId})。服务器真的不应该关心用户如何进入该POST,只是它应该将该产品添加到用户的购物车并将更新的购物车表示返回给用户。然后,只有当购物车中有一个或多个商品时,用户界面才可以使用javascript来确定是否显示结帐链接。

因此,您的工作流似乎位于REST服务之外,而是由页面中的导航定义,导航在用户请求时与您的REST服务进行交互。根据用户设置的状态,您可能拥有必须在应用程序中进行的内部工作流程,这当然是可能的。但您似乎在描述的是网站内的用户交互,虽然这确实是一个工作流程,但您的UI似乎比专用的服务器端组件/层更好地定义。

答案 2 :(得分:1)

您触及API的工作流程(又称业务逻辑)部分。从技术上讲,这是API部分的一个独立问题,即API接口。当然,正如您所提到的,HATEOAS允许您建议某些有效的操作,但您应该小心维护statelessness

  

在REST应用程序中,服务器端不能存储会话状态。相反,它必须完全由客户端处理。

     

因此,如果服务器上存在会话状态,则不是REST。

对于购物车示例,您可以将状态保存在Redis等单独的缓存层中。至于你的工作流程。您不希望在域模型中计算购物车或总帐单等业务逻辑。这将被添加到服务层。

你谈到了恶作剧用户猜测网址。这始终是一个问题,应由您的安全人员处理。如果要删除用户的网址为DELETE /user/3782,则可以轻松猜出如何删除所有用户。但是你不应该只依赖于混淆URL。您应该在端点内部进行真正的安全性和访问检查,检查每个请求是否有效。

这是针对您的购物车问题的相同解决方案您需要授予一个令牌,该令牌将附加其购物信息并使用该令牌验证每个操作,无论他们是否知道正确的URL。在安全性方面没有捷径。

答案 3 :(得分:-1)

您可能希望按照DDD(域驱动设计)的方式重新定位您的架构,并且可能使用MSA,这样您就可以从编排的工作流转换到EDA和微过程的编排。