简体   繁体   English

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

[英]RESTful API: Where should I code my workflow?

I am developing a RESTful API. 我正在开发RESTful API。 This is my first API, but also my first really big coding project. 这是我的第一个API,也是我的第一个非常大的编码项目。 As such, I'm still learning a lot about architecture etc. 因此,我仍然在学习很多有关建筑等方面的知识。

Currently, I have my api setup in the following layers: 目前,我在以下层中设置了api:

  • HTTP Layer HTTP层
  • Resource Layer 资源层
  • Domain Model / Business Logic Layer 域模型/业务逻辑层
  • Data Access / Repository Layer 数据访问/存储库层
  • Persistent Storage / DB Layer 持久存储/数据库层

The issue I have run into at the moment is where do I need to put workflow objects / managers? 我目前遇到的问题是我需要在哪里放置工作流对象/经理? By workflows, I mean code that evaluates what next step is required by the end user. 按工作流程,我的意思是评估最终用户下一步所需的代码。 For example, an e-commerce workflow. 例如,电子商务工作流程。 User adds item to basket, then checks out, then fills in personal details, then pays. 用户将项目添加到购物篮,然后签出,然后填写个人详细信息,然后付款。 The workflow would be responsible for deciding what steps are next, but also what steps are NOT allowed. 工作流程将负责决定接下来的步骤,以及不允许的步骤。 For example, a user couldn't cause errors in the API by trying to pay before they have entered personal details (maybe they recall the URI for payments and try to skip a step). 例如,用户不能通过在输入个人详细信息之前尝试付款来导致API中的错误(可能他们回想起付款的URI并尝试跳过一个步骤)。 The workflow would check to see that all previous steps had been completed, if not, would not allow payment. 工作流程将检查以前所有步骤是否已完成,如果没有,则不允许付款。

Currently, my workflow logic is in the Resource Layer. 目前,我的工作流逻辑位于资源层中。 I am using hypermedia links to present the workflow to the user eg providing a 'next step' link. 我正在使用超媒体链接向用户呈现工作流程,例如提供“下一步”链接。 The problem I have with this is that the resource layer is a top level layer, and more aligned with presentation. 我遇到的问题是资源层是顶级层,并且与表示更加一致。 I feel it needs to know too much about the underlying domain model to effectively evaluate a workflow ie it would need to know it has to check the personal_detail s entity before allowing payment. 我觉得需要对底层域模型有太多了解才能有效地评估工作流,即它需要知道它必须在允许付款之前检查personal_detail的实体。

This now leads me to thinking that workflows belong in the domain model. 这让我想到工作流属于域模型。 This does make a lot more sense, as really workflows are part of the business logic and I think are therefore best placed in the domain layer. 这确实更有意义,因为真正的工作流是业务逻辑的一部分,因此我认为最好放在域层中。 After all, replace the Resource Layer with something else, and you would still need the underlying workflows. 毕竟,用其他东西替换资源层,您仍然需要基础工作流。

But now the problem is that workflows required knowledge of several domain objects to complete their logic. 但现在问题是工作流需要知道几个域对象才能完成其逻辑。 It now feels right that it maybe goes in its own layer? 它现在感觉是对的,它可能会在自己的层中? Between Resource and Domain Layer? 在资源和域层之间?

  • HTTP Layer HTTP层
  • Resource Layer 资源层
  • Workflow Layer 工作流层
  • Domain Model / Business Logic Layer 域模型/业务逻辑层
  • Data Access / Repository Layer 数据访问/存储库层
  • Persistent Storage / DB Layer 持久存储/数据库层

Im just wondering if anyone had any other views or thoughts around this? 我只是想知道是否有人对此有任何其他意见或想法? As I said, I have no past application experience to know where workflows should be placed. 正如我所说,我没有过去的应用经验来了解应该放置工作流程的位置。 Im really just learning this for the first time so want to make sure I'm going about it the right way. 我真的只是第一次学习这个,所以想要确保我正确的方式。

Links to articles or blogs that cover this would be greatly appreciated. 我们将非常感谢您对文章或博客的链接。 Love reading up on different implementations. 喜欢阅读不同的实现。

EDIT 编辑

To clarify, I release that HATEOAS allows the client to navigate through the 'workflow', but there must be something in my API that knows what links to show ie it is really defining the workflow that is allowed. 为了澄清,我发布HATEOAS允许客户端浏览“工作流程”,但我的API中必须有一些知道要显示的链接,即它确实定义了允许的工作流程。 It presents workflow related links in the resource, but additionally it validates requests are in sync with the workflow. 它在资源中显示与工作流相关的链接,但另外它验证请求与工作流同步。 Whilst I agree that a client will probably only follow the links provided in the resource, the danger (and beauty) of rest, is that its URI driven, so there is nothing stopping a mischievous client trying to 'skip' steps in the workflow by making an educated guess at the URI. 虽然我同意客户可能只会遵循资源中提供的链接,但是休息的危险(和美)是它的URI驱动,所以没有什么可以阻止恶作剧客户试图通过以下方式“跳过”工作流程对URI进行有根据的猜测。 The API needs to spot this and return a 302 response. API需要发现这一点并返回302响应。

The answer to this question has taken me a fair bit of research, but basically the 'workflow' part has nothing to do with REST at all and more to do with the application layer. 这个问题的答案让我得到了相当多的研究,但基本上“工作流程”部分与REST完全无关,而与应用层有关。

My system was had the application logic and REST API too tightly coupled. 我的系统有应用程序逻辑和REST API太紧密耦合。 I solved my problem by refactoring to reduce the coupling and now the workflow lives within the context of the application 我通过重构来减少耦合来解决我的问题,现在工作流程仍然存在于应用程序的上下文中

REST encourages you to create a vocabulary of nouns (users, products, shopping carts) against an established set of verbs (GET, POST, PUT, DELETE). REST鼓励您根据已建立的动词集(GET,POST,PUT,DELETE)创建名词词汇(用户,产品,购物车)。 If you stick to this rule, then in your example the workflow really is defined by the set of interactions the user has with your site. 如果您遵守此规则,那么在您的示例中,工作流实际上是由用户与您的站点进行的交互集定义的。 It is how the user uses your app, which is really defined by the UI. 这是用户使用您的应用程序的方式,它实际上是由UI定义的。 Your REST services should react appropriately to invalid state requests, such as attempting to checkout with an empty cart, but the UI may also prevent such requests using script, which is an optional characteristic of REST. 您的REST服务应该对无效状态请求做出适当的反应,例如尝试使用空购物车结帐,但UI也可能使用脚本阻止此类请求,这是REST的可选特性。

For example, the UI which displays a product to the user might also display a link which would permit the user to add that product to their cart (POST shoppingcart/{productId}). 例如,向用户显示产品的UI也可能显示允许用户将该产品添加到其购物车的链接(POST shoppingcart / {productId})。 The server really shouldn't care how the user got to that POST, only that it should add that product to the user's cart and return an updated representation of the cart to the user. 服务器真的不应该关心用户如何进入该POST,只是它应该将该产品添加到用户的购物车并将更新的购物车表示返回给用户。 The UI can then use javascript to determine whether or not to display a link to checkout only if the shopping cart has one or more items. 然后,UI可以使用javascript来确定仅在购物车具有一个或多个项目时是否显示要结账的链接。

So it seems that your workflow lives outside the REST service and is rather defined by the navigation in your pages, which interact with your REST services as the user requests things. 因此,您的工作流似乎位于REST服务之外,而是由页面中的导航定义,这些导航在用户请求时与您的REST服务进行交互。 It's certainly possible that you might have internal workflows which must occur within your application based on the states setup by the user. 您当然可能拥有必须在应用程序中根据用户设置的状态进行的内部工作流程。 But what you seem to be describing is a user interaction within the site, and while that's indeed a workflow, it seems better defined by your UI(s) than by a dedicated server-side component/layer. 但您似乎在描述的是网站内的用户交互,虽然这确实是一个工作流程,但它似乎更好地由您的UI定义,而不是由专用的服务器端组件/层定义。

You touch on the workflow (aka business logic) part of an API. 您可以触及API的工作流程(也称为业务逻辑)。 Technically this is a separate concern from the API part which is the interface. 从技术上讲,这是API部分的一个独立问题,即API接口。 Sure, as you mention, HATEOAS allows you to suggest certain actions which are valid, but you should be careful to maintain statelessness . 当然,正如你所提到的,HATEOAS允许你建议某些有效的行为,但你应该小心保持无国籍状态

In REST applications, there must not be session state stored on the server side. 在REST应用程序中,服务器端不得存储会话状态。 Instead, it must be handled entirely by the client. 相反,它必须完全由客户端处理。

So, if there's session state on the server, it's not REST. 因此,如果服务器上存在会话状态,则不是REST。

For your shopping cart example, you can save state in a separate caching layer like Redis. 对于购物车示例,您可以将状态保存在Redis等单独的缓存层中。 As for your workflows. 至于你的工作流程。 You wouldn't want to put business logic like calculating their shopping cart or total bill in a domain model. 您不希望在域模型中计算购物车或总帐单等业务逻辑。 That would be added to service layer. 这将被添加到服务层。

You talked about mischievous users guessing URLs. 你谈到了恶作剧用户猜测网址。 This is always a concern and should be handled by your security. 这始终是一个问题,应由您的安全人员处理。 If the URL to delete a user is DELETE /user/3782 ... they can easily guess how to delete all the users. 如果删除用户的URL是DELETE /user/3782 ......他们可以轻松猜出如何删除所有用户。 But you shouldn't rely only on obfuscating the URLs. 但是你不应该只依赖于混淆URL。 You should have real security and access checks inside your endpoints checking if each request is valid. 您应该在端点内部进行真正的安全性和访问检查,检查每个请求是否有效。

This is the same solution for your shopping cart concerns You'll need to grant a token which will attach their shopping information and use that to validate each action, regardless if they knew the right URL or not. 这是针对您的购物车问题的相同解决方案您需要授予一个令牌,该令牌将附加他们的购物信息并使用它来验证每个操作,无论他们是否知道正确的URL。 There are no shortcuts when it comes to security. 在安全方面没有捷径可走。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM