NodeJS REST API模型和服务结构

时间:2014-11-29 18:48:41

标签: node.js model-view-controller express

我正在使用Express和MariaDB / Cassandra作为我的后端编写中等规模的应用程序。

我试图遵循模型服务控制器模式。我最初的设计有瘦控制器和胖模型,但我觉得模型包含很多代码,可能需要分解成单独的文件。所以现在我有一个位于控制器和模型之间的服务层。

我试图在Controller / API方法和服务方法之间实现1-1映射。

每个服务方法都会尝试包含该API方法要执行的所有操作的代码。我的验证逻辑在服务中。然后,此服务可以使用async nodejs模块在内部调用多个模型,处理并将响应传递给其他模型。但这证明是一个问题。

想象一下,我注册了一个用户,每个用户都属于一个组织。 -

  1. 我检查用户是否已经存在。
  2. 如果不是,我为用户创建了一个组织。
  3. 我获得了组织ID。
  4. 我创建了用户,将组织ID映射到用户的表中。
  5. 所有这些都是在交易中进行的。

    如果我将验证放入服务中,那么即使我没有用于插入组织的控制器/ API,我也必须有一个用于插入组织的服务,以便可以在那里执行验证。这将打破Service和Controller / API之间的1-1映射。

    将验证放入模型中的另一个问题是它将在插入组织或用户之前立即执行。现在,如果组织数据正确,但用户数据不正确,实际上将插入组织,但必须回滚。

    有没有更好的方法来解决这个问题?我应该最初在服务中执行用户和组织的验证,然后在模型中再次执行它还是有更好的方法来处理它?我愿意进行大幅度的改变。

1 个答案:

答案 0 :(得分:2)

不幸的是,没有干净的好办法来处理这个问题。我不熟悉使用MariaDB / Cassandra,但我使用Express / Mongooose / MongoDB进行了此操作。问题是有时您需要执行与数据库无关的验证 - 即联系表单,其他一些非数据库操作。有时,您需要对诸如唯一字段检查之类的事情进行数据库本机验证。在Mongoose的情况下,已经尝试创建基于服务的验证器来检查唯一性,但是它们(根据Mongoose作者)在100%的时间内可能由于竞争条件而不能工作。

我接近这个的方法是创建一个前端/路由验证服务/中间件来检查所需的参数等。其中一些可以在数据库中处理,但是,如在联系表单的情况下,一些只需要在服务中。我已经以多种方式扩展了Error对象(对于未找到的资源,前端验证等)来处理这些错误消息。

然后我确保所有错误(前端服务,Mongo,Mongoose)冒泡并使用next(err)在我的控制器中传递。然后将所有错误汇集到错误中间件中,该错误中间件将不同的错误模型转换为统一格式,然后输出到json。最终结果是在保持非常干净的设置的同时处理错误的位置具有很大的灵活性。